#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 создала бы и заполнила ее изначально, если бы вы использовали предполагаемый рабочий процесс миграции.