Как откатить транзакцию в Entity Framework
string[] usersToAdd = new string[] { "asd", "asdert", "gasdff6" };
using (Entities context = new Entities())
{
foreach (string user in usersToAdd)
{
context.AddToUsers(new User { Name = user });
}
try
{
context.SaveChanges(); //Exception thrown: user 'gasdff6' already exist.
}
catch (Exception e)
{
//Roll back all changes including the two previous users.
}
Или, может быть, это делается автоматически, что означает, что в случае возникновения ошибки фиксация изменений отменяется для всех изменений. это?
2 ответа
Хорошо
Я создал образец приложения, подобный примеру, из вопроса и послесловий, которые я проверил в БД, и пользователи не были добавлены.
Вывод: ObjectContext.SaveChange это автоматически транзакция.
Примечание: я считаю, что транзакции будут необходимы при выполнении sprocs и т. Д.
Я считаю (но я уже давно не эксперт по EF), что до вызова context.SaveChanges транзакция не начинается. Я ожидаю, что Исключение от этого вызова автоматически откатит любую транзакцию, которую он начал. Альтернативы (в случае, если вы хотите контролировать транзакцию) [из книги "Programming Entity Framework" Дж. Лермана, O'Reilly, pg. 618]
using (var transaction = new System.Transactions.TransactionScope())
{
try
{
context.SaveChanges();
transaction.Complete();
context.AcceptAllChanges();
}
catch(OptimisticConcurrencyException e)
{
//Handle the exception
context.SaveChanges();
}
}
или же
bool saved = false;
using (var transaction = new System.Transactions.TransactionScope())
{
try
{
context.SaveChanges();
saved = true;
}
catch(OptimisticConcurrencyException e)
{
//Handle the exception
context.SaveChanges();
}
finally
{
if(saved)
{
transaction.Complete();
context.AcceptAllChanges();
}
}
}