С Entity Framework большей части времени SaveChanges()
достаточно. Это создает транзакцию или участвует в любой внешней транзакции и выполняет всю необходимую работу в этой транзакции.
Иногда, хотя SaveChanges(false) + AcceptAllChanges()
спаривание полезно.
Самое полезное место для этого - ситуации, когда вы хотите выполнить распределенную транзакцию в двух разных контекстах.
Т.е. как то так (плохо)
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();
}
Если context1.SaveChanges()
успешно, но context2.SaveChanges()
не удается, вся распределенная транзакция прерывается. Но, к сожалению, Entity Framework уже отменил изменения context1
, поэтому вы не можете воспроизвести или эффективно зарегистрировать ошибку.
Но если вы измените свой код, чтобы он выглядел так:
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();
}
В то время как вызов SaveChanges(false)
отправляет необходимые команды в базу данных, сам контекст не изменяется, поэтому вы можете сделать это снова, если необходимо, или вы можете опросить, ObjectStateManager
если хотите.
Это означает, что если транзакция фактически выдает исключение, которое вы можете компенсировать, повторяя попытку или регистрируя состояние каждого контекста ObjectStateManager
где-либо.
Смотрите мой блог для получения дополнительной информации.
SaveChanges(fase); ... AcceptAllChanges();
был шаблон в первую очередь. Обратите внимание, как принятый ответ на вышеупомянутый вопрос написан автором блога - и на этот блог есть ссылка в другом вопросе. Это все вместе.