Avec Entity Framework, la plupart du temps SaveChanges()
est suffisante. Cela crée une transaction, ou enrôle dans toute ambiante transaction, et prend en charge tous les travaux nécessaires à cette transaction.
Parfois, si l' SaveChanges(false) + AcceptAllChanges()
le couplage est utile.
La plus utile au lieu de cela est dans les situations où vous souhaitez effectuer une transaction distribuée dans deux Contextes différents.
I. e. quelque chose comme ceci (mauvais):
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()
réussit, mais context2.SaveChanges()
d'échec de l'ensemble de la distributed transaction est annulée. Mais malheureusement, le Cadre de l'Entité a déjà jeté des modifications sur l' context1
, de sorte que vous ne pouvez pas rejouer ou efficacement journal de l'échec.
Mais si vous modifiez votre code ressemble à ceci:
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();
}
Alors que l'appel à l' SaveChanges(false)
envoie les commandes nécessaires à la base de données, le contexte lui-même n'est pas modifié, de sorte que vous pouvez le faire à nouveau si nécessaire, ou vous pouvez interroger l' ObjectStateManager
si vous le souhaitez.
Cela signifie que si l'opération s'interrompt, vous pouvez compenser, re-essayer ou l'enregistrement de l'état de chacun des contextes ObjectStateManager
quelque part.
Voir mon blog pour plus d'.