Откат добавлений / удалений в DBSets DbContext с использованием транзакции в Entity Framework - PullRequest
0 голосов
/ 12 сентября 2018

Общий шаблон для меня в проекте, использующем Entity Framework 6:

  1. Создание новых сущностей для добавления
  2. Добавление сущностей в соответствующие DBSet из DbContext
  3. Установить свойства этих объектов
  4. Вызов DbContext.SaveChanges()

Вот некоторый псевдокод для того, что я имею в виду:

    // Psuedo code to illustrate process. 
    void AddProcess()
    {

        var modelsToAdd = GetModelsToAdd();

        try
        {
            _context.Models.AddRange(modelsToAdd);

            _context.SaveChanges();

            // If we get here all is good.
        }
        catch (Exception ex)
        {
            _context.RemoveRange(modelsToAdd);
            throw;
        }
        finally
        {
            //....
        }
    }

Мне известно, что метод SaveChanges() внутренне создает свой собственный Transaction, поэтому при возникновении исключения во время сохранения он будет откатан.Однако я хочу, чтобы добавленные сущности в (2) были удалены из DbSet, если во время SaveChanges() произойдет ошибка.По сути, как будто процесс «Добавить» никогда не происходил.

Как видите, в данный момент я кеширую список задействованных моделей, а затем удаляю их, если происходит исключение.

То, что я хотел бы знать, есть ли лучший способсделать это с Транзакциями, автоматически выполняющими работу за меня?Итак, может ли внутренний Transaction откат SaveChanges() также откатить какие-либо дополнения к DbSet?Или можно использовать другие транзакции?

Каков наилучший / предпочтительный способ достижения того, что я ищу?Я довольно новичок в EF, так что это может быть чем-то очевидным.

1 Ответ

0 голосов
/ 12 сентября 2018

Опция № 1 из https://code.msdn.microsoft.com/How-to-undo-the-changes-in-00aed3c4 обычно достаточна для большинства реализаций, где вы хотите откатить изменения в DbContext без удаления и повторной создания контекста. Обычно запрос был бы неудачным, и вызов завершился бы, поэтому область действия DbContext должна заканчиваться, пока не будет предпринята попытка повторной попытки в новом запросе.

Я бы смотрел на откат DbContext только в том случае, если бы была действительно веская причина для немедленного повтора / альтернативного действия. Желание откатить DbSets в случае сбоя SaveChanges обычно является показателем того, что DbContext слишком долго сохраняется в живых.

В таких важных вещах, как ведение журнала, которое необходимо сохранить в случае сбоя, следует использовать выделенный DbContext, чтобы их обновления не препятствовали сбоям SaveChanges в DbContext приложения.

...