Обновление базы данных ядра EF указывает базовую версию

#c# #entity-framework-core #entity-framework-migrations

#c# #сущность-фреймворк-ядро #entity-framework-миграции

Вопрос:

В моих проектах у меня есть два файла миграции ядра EF в папке Migrations, которые я создал на основе первоначального выпуска и после обновления. Начальная миграция («Начальная») содержит много CreateTable инструкций, тогда как вторая миграция («Очистка») содержит только несколько DropColumn инструкций в их Up методах.

Моя база данных была создана путем вызова context.Database.EnsureCreated() между первой и второй миграцией, т. Е. Теперь я хотел бы выполнить вторую миграцию. Однако, если я вызываю dotnet ef database update Cleanup , я получаю сообщение об ошибке:

 Applying migration '20190409043916_Initial'.
Failed executing DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [LongRunningOperations] (
    [Id] bigint NOT NULL IDENTITY,
    [Start] datetime2 NOT NULL,
    [End] datetime2 NULL,
    [Discriminator] nvarchar(max) NOT NULL,
    CONSTRAINT [PK_LongRunningOperations] PRIMARY KEY ([Id])
);
System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'LongRunningOperations' in the database.
  

Очевидно, что EF также хочет применить первую миграцию. Есть ли возможность указать базовую версию базы данных? Могу ли я сделать что-то еще, чтобы избежать выполнения «начальной» миграции?

Более общий вопрос, который может помочь мне понять, что происходит: как ядро EF определяет, какова базовая версия, то есть какие миграции должны быть выполнены?

Комментарии:

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

2. @JAZ правильно, таблица, которую вы ищете __EFMigrationsHistory , и MigrationId должна соответствовать имени вашей миграции (например, «20190410160507_LongRunningOperations»)

3. спасибо, это все. Вы можете сделать это ответом, если хотите.

Ответ №1:

Моя база данных была создана вызовом context.Database.EnsureCreated()

В этом корень проблемы. Документация для создания и удаления API-интерфейсов содержит следующее:

Предупреждение

EnsureCreated и миграции плохо работают вместе. Если вы используете миграции, не используйте EnsureCreated для инициализации схемы.

и затем:

Переход от EnsureCreated к Migrations не является плавным процессом. Самый простой способ сделать это — удалить базу данных и заново создать ее с помощью миграции. Если вы планируете использовать миграции в будущем, лучше всего просто начать с миграций, а не использовать EnsureCreated.

Аналогично применяйте миграции во время выполнения:

Предупреждение

  • Не вызывайте EnsureCreated() раньше Migrate() . EnsureCreated() обходит миграции для создания схемы, что приводит Migrate() к сбою.

Вкратце, вы должны были использовать либо инструменты ядра EF, либо context.Database.Migrate() для создания / обновления базы данных.

Поскольку вы сделали это неправильно, либо следуйте их рекомендации «удалить базу данных и заново создать ее с помощью миграций», либо попробуйте восстановить таблицу истории миграций так, как EF Core создала бы и заполнила ее изначально, если бы вы использовали предполагаемый рабочий процесс миграции.