tuve problemas similares, que se produjo en EF6 (funcionaba en EF4 sin transacciones, EF 4 utilizadas transacciones implícitas con el alcance derecha).
Solo crear una nueva entidad y guardarla no me ayudó en mi caso (ver los comentarios de las otras respuestas, tenían problemas similares con el uso de dc.SaveChanges()
solo para la actualización automática).
Consideremos el siguiente código (CustomerId
es la clave principal con incremento automático):
public void UpdateCustomer(string strCustomerName, string strDescription)
{
using (var transaction = CreateTransactionScope())
{
MyCustomer tbl=null;
Func<MyCustomer, bool> selectByName=(i => i.CustomerName.Equals(strCustomerName));
var doesRecordExistAlready = dc.MyCustomers.Any(selectByName);
if (doesRecordExistAlready)
{
// Updating
tbl=dc.MyCustomers.Where(selectByName).FirstOrDefault();
tbl.Description=strDescription;
}
else
{
// Inserting
tbl=new MyCustomer();
var maxItem=
dc.MyCustomers.OrderByDescending(i => i.CustomerId).FirstOrDefault();
var newID = maxItem==null ? 1 : maxItem.CustomerId+1;
tbl.CustomerId=newID;
tbl.CustomerName=strCustomerName;
tbl.Description=strDescription;
dc.MyCustomers.AddObject(tbl);
}
dc.SaveChanges(); // save all changes consistently
transaction.Complete(); // commit
}
}
Y la función de ayuda para crear el contexto de transacción correcta es:
// creates the right transaction scope
public static System.Transactions.TransactionScope CreateTransactionScope()
// needs to add ref: System.Transactions
{
var transactionOptions = new TransactionOptions
{
IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted,
Timeout = new TimeSpan(0,0,10,0,0) //assume 10 min is the timeout time
};
var scopeOption=TransactionScopeOption.RequiresNew;
var scope = new System.Transactions.TransactionScope(scopeOption,
transactionOptions);
return scope;
}
El truco está aquí , para permitir la lectura no confirmada, por lo tanto, puede consultar la ID máxima y agregar 1 a la ID. Lo que no pude lograr es permitir que SQL Server genere el ID automáticamente, porque EF me permite no omitir el CustomerId
al momento de la creación.
Para leer más acerca ámbito de transacción, look here.
Sí, generalmente a partir de las piezas generadas VS2010 tendrá que establecer el Valor StoreGenerated en el bloque grande superior de xml. Obtendrá varias claves primarias porque, a menos que lo cambie, EF genera la ID para usted, como 0. – Rangoric
Es una locura que todavía no hayan resuelto este error omnipresente. ¡Es la versión 4, vamos equipo de EF! – arviman
Muchas veces, las personas olvidan marcar la columna con un valor de identidad e incremento automático. EF lo recoge de la base de datos. – arviman