Con Entity Framework, la mayoría de las veces SaveChanges()
es suficiente. Esto crea una transacción, o se alista en cualquier transacción ambiental, y realiza todo el trabajo necesario en esa transacción.
A veces, aunque el SaveChanges(false) + AcceptAllChanges()
emparejamiento es útil.
El lugar más útil para esto es en situaciones en las que desea realizar una transacción distribuida en dos contextos diferentes.
Es decir, algo como esto (malo):
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save and discard changes
context1.SaveChanges();
//Save and discard changes
context2.SaveChanges();
//if we get here things are looking good.
scope.Complete();
}
Si context1.SaveChanges()
tiene éxito pero context2.SaveChanges()
falla, se anula toda la transacción distribuida. Pero desafortunadamente, Entity Framework ya ha descartado los cambios context1
, por lo que no puede reproducir o registrar efectivamente la falla.
Pero si cambia su código para que se vea así:
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save Changes but don't discard yet
context1.SaveChanges(false);
//Save Changes but don't discard yet
context2.SaveChanges(false);
//if we get here things are looking good.
scope.Complete();
context1.AcceptAllChanges();
context2.AcceptAllChanges();
}
Si bien la llamada a SaveChanges(false)
envía los comandos necesarios a la base de datos, el contexto en sí no cambia, por lo que puede hacerlo nuevamente si es necesario, o puede interrogar ObjectStateManager
si lo desea.
Esto significa que si la transacción realmente arroja una excepción que puede compensar, ya sea reintentando o registrando el estado de cada contexto en ObjectStateManager
alguna parte.
Vea mi publicación de blog para más.
SaveChanges(fase); ... AcceptAllChanges();
era un patrón en primer lugar. Observe cómo la respuesta aceptada a la pregunta anterior está escrita por el autor de un blog , y ese blog se menciona en la otra pregunta. Todo se une.