Как сохранить информацию отслеживания изменений Db Context & Restore? - PullRequest
2 голосов
/ 03 мая 2019

Мы должны обнаружить изменения внутри контекста БД и запланировать обновление БД на более позднюю дату.

Как сохранить изменить информацию трекера контекста БД во временнуюБаза данных, чтобы впоследствии их можно было восстановить в другой экземпляр DbContext.

Так что просто .SaveChanges на вновь созданном экземпляре Db Context должен зафиксировать ожидающие изменения.

Ответы [ 2 ]

3 голосов
/ 13 мая 2019

Я могу придумать два решения:

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

  2. Дублирование существующей таблицы (только структура) на сервере, это позволяет сгенерированным классам EFповторное использование, называется запросами.После утверждения используйте запрос SQL, чтобы добавить запись в основную таблицу, и удалите строку из таблицы запросов.Если запрос отклонен, вы можете добавить его в таблицу отказа, указав причину отклонения.

Преимущества этих методов:

  1. Поскольку все операции выполняются в одной и той же базе данных, в отличие от локальных или разных баз данных, это означает, что возможны атомарные транзакции и использование существующих политик резервного копирования / восстановления / доступности.

  2. (#2) Можно создать историю, дающую информацию об ответственности.

3 голосов
/ 10 мая 2019

Все, что вам нужно сделать, возможно, это иметь локальную временную базу данных, которая имеет ту же структуру, что и ваша основная (удаленная) база данных; затем выполните SaveChanges в локальной базе данных, а не в основной базе данных.

Чтобы направить SaveChanges к локальной базе данных вместо основной, при создании DbContext вам просто потребуется использовать другую строку подключения. (Хотя было некоторое обсуждение возможности изменить соединение в DbContext, в настоящее время оно не реализовано, см. https://github.com/aspnet/EntityFrameworkCore/issues/8494.).

Итак ... скажем, ваши изменения находятся в "основном" DbContext, вы затем создаете второй DbContext для локальной базы данных и просто копируете изменения из основного "DbContext.ChangeTracker" в "локальный" DbContext. ChangeTracker. Вы можете сделать это, перебирая записи ChangeTracker и: клонируйте сущность (создайте сущность и скопируйте все значения из EntityEntry.OriginalValues, используя PropertyInfo.SetValue); прикрепить объект к «локальному» DbContext; затем примените изменения (получите текущее значение, используя EntityEntry.CurrentValues, проверьте на! EqualityComparer.Default.Equals и, если не равно, снова используйте PropertyInfo.SetValue, чтобы применить текущее значение).

Это довольно просто, если вам нужна только мелкая копия; если вам нужна глубокая копия, вам также нужно будет перемещаться по отношениям, которые есть в модели.

В качестве альтернативы всему этому другой подход состоял бы в том, чтобы всегда сохранять все в локальной базе данных и затем иметь отдельный процесс, такой как пакетный процесс, который копирует значения в основную базу данных. В качестве общего комментария, независимо от того, как вы это сделаете, вам придется иметь дело с любыми конфликтами параллелизма, которые могут возникнуть, когда локальные значения отправляются в основную базу данных.

Steve

P.S. Возможно, стоит поэкспериментировать с DbContext.Database, чтобы увидеть, можете ли вы перенаправить соединение - если вы хотите выйти за пределы «поддерживаемого» API.

...