Метод Rollback EntityFramework

313
17 января 2017, 22:11

Подскажите, пожалуйста, как реализовать Rollback используя EntityFramework 6.x, а так же паттерн Unit of work. Для этого имеется класс интерфейс IUnitOfWork

public interface IUnitOfWork : IDisposable
{
   void Commit();
   // void Rollback();
}

и класс - UnitOfWork

    public class UnitOfWork : IUnitOfWork 
    {
        public DbContext Context { get; private set; }
        public UnitOfWork(DbContext context)
        {
            Context = context;
        }
        public void Commit()
        {            
            if (Context != null)
            {
                Context.SaveChanges();
            }
        }
        public void Dispose()
        {
            if (Context != null)
            {
                Context.Dispose();
            }
        }
    }

Знаю что на уровне T-SQL это задается таким образом:

BEGIN TRANSACTION
  // операции взаимодействия
  IF (@@error <> 0)
        ROLLBACK
COMMIT

UPD

Планируется использоваться так

try
{
    repository.Delete(...);
    unitOfWork.Commit();
}
catch
{
   unitOfWork.Rollback();
   // регистрация ошибки
}
Answer 1

Просто вызовите Dispose не вызывая Commit. Или вручную в finally, или с использованием using:

using (var unitOfWork = new UnitOfWork(context))
{
    repository.Delete(...);
    unitOfWork.Commit();
}
catch
{
   // регистрация ошибки
}

Если ошибка произойдет до вызова SaveChanges - изменения будут просто выброшены Dispose-ом обертки и контекста.

Если ошибка произойдет в процессе выполнения SaveChanges - то будет откачена транзакция SQL, которую EF открывает в начале SaveChanges и коммитает после сохранения всех изменений.

Только не забывайте, что на самом деле контекст в EF - это и есть готовая реализация паттернов Unit Of Work + Repository. А ваш UnitOfWork - это просто прокси-обертка, которая сама по себе UoW не реализует - она просто отделяет интерфейс UoW от репозитория.

Поэтому контекст у вас должен живет у вас не дольше обертки, так что вы не сможете (и не должны) использовать его повторно для другого экземпляра UnitOfWork.

Answer 2

Аналогичный вопрос задавал пользователь на английском StackOverflow: How to rollback a transaction in Entity Framework. Проведя эксперимент, он выяснил что в случае ошибки которая возникает при вызове метода DbContext.SaveChanges, Entity Framework автоматически откатывает все изменения.

READ ALSO
Передача данных между двумя DataGridView

Передача данных между двумя DataGridView

На форме есть два dataGridViewВ первом отображается поиск из базы, во второй должны записываться необходимые строки из результата поиска

443
Как сократить логическое выражение?

Как сократить логическое выражение?

Можно ли как нибудь переписать вот это условие в более короткий вариант?

332
Spinbox не помогает [требует правки]

Spinbox не помогает [требует правки]

Тут спин в норме http://trueshikinn

335
Что с пассивной подпиской на события?

Что с пассивной подпиской на события?

Обнаружил интересную фичу - подписку на события с указанием passsive: true, что должно позволить браузеру оптимизировать стандратные действия,...

395