Entity Framework Core - более ранние миграции данных прерываются при изменении моделей - PullRequest
2 голосов
/ 03 октября 2019

Мы запускаем новое приложение с .NET Core, EF Core и Postgres - нам действительно нравятся миграции: -)

Однако я обнаружил проблему, которую не могу понятькак обойти. В некоторых наших миграциях мы используем DbContext для загрузки записей, запуска некоторой бизнес-логики и повторного сохранения записей. Мы также запускаем database.Context.Migrate() при запуске веб-сервера, поэтому он всегда работает.

Пока все работает нормально.

К сожалению, он работает до тех пор, пока модель не изменится припозже точка. Рассмотрим следующий порядок миграции:

  1. Создание моделей Customer, Order и OrderLine. Добавьте миграции схемы для загрузки структур
  2. Изменилось бизнес-правило, поэтому нам нужно установить значение для записи Order на основе некоторой бизнес-логики. Мы создаем миграцию данных, где загружаем DbContext, запускаем код и запускаем SaveChangesAsync()

    На этом этапе все в порядке.

  3. Нам нужнодобавить миграцию схемы с новым полем в запись Customer.

Здесь все обрывается. Если к базе данных не применена миграция 2, команда Migrate() выдает ошибку, как при применении миграции 2, EF пытается сгенерировать оператор выбора, который включает новое поле в 3.

Я не уверен, гдепроблема на самом деле в процессе: разве мы не должны использовать DbContext при миграции (и операторы SQL с ручным кодом)? Должны ли мы явно делать прогнозы для каждой прочитанной записи, чтобы точно знать, что мы делаем?

Что-то еще?

1 Ответ

1 голос
/ 03 октября 2019

В вашем примере 1 и 3 - это миграции схем, а 2 - миграция данных.

Поскольку Entity Framework Core будет генерировать запросы на основе текущих моделей в коде, а не текущего состояния базы данных,Существует два варианта обработки переноса данных.

  1. Выполнение переноса данных по порядку с переносом схемы

    Используйте что-то вроде Dapper или ADO.NET для выполнения миграции данных на основе схемы во время записи миграции. Вы можете получить объект DbConnection из контекста EF, используя context.Database.GetDbConnection()

    Плюсы: Код миграции никогда не потребуется изменять

    Минусы: Вы не получите никаких преимуществ EF Core

  2. Выполнение миграции данных после миграции схемы

    EF выполняет миграции в восходящем направлениипорядок строкового значения MigrationAttribute.Id. EF генерирует это на основе временной отметки при вызове dotnet ef migrations add xxx. Вы можете изменить этот атрибут, чтобы обеспечить миграцию данных после всех миграций схемы. Также измените имя файла для удобства чтения, чтобы они оставались в том порядке, в котором они будут применены.

    Плюсы: Вы получаете все преимущества EF Core

    Минусы: Если в будущем схема изменится, например, удалит столбец, на который ссылается миграция данных, вам нужно будет изменить миграцию

    Пример MigrationAttribute.Id изменить:

// change
[Migration("20191002171530_DataMigration")]
// to
[Migration("99999999000001_DataMigration")]
...