Entity Framework, автоматическое применение миграции
Я использую Entity Framework Code First с помощью AutomaticMigrationsEnabled = true
:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DbContext, MigrateDBConfiguration>());
//////////////////////////////////
public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<DbContext>
{
public MigrateDBConfiguration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
При первом запуске проекта создается база данных и таблицы, как и ожидалось. После изменения моей модели путем добавления или удаления полей я запустил Add-Migration
. Класс Migration создан, но после запуска проекта возникает исключение:
Исключение типа "System.InvalidOperationException" возникло в EntityFramework.dll, но не было обработано в коде пользователя
Дополнительная информация: модель, поддерживающая контекст DBContext, имеет изменено с момента создания базы данных.
ОБНОВЛЕНИЕ: В соответствии с указаниями в ответе arturo menchaca я изменил свой код следующим образом:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DBContext, MigrateDBConfiguration<DBContext>>());
...
После изменения возникает исключение:
В базе данных уже есть объект с именем "MyTable".
Как я могу применить миграцию моей базы данных?
Ответы
Ответ 1
Наконец, я нашел решение своей проблемы. Я вызываю этот метод в каждом запуске приложения:
public void InitializeDatabase(DataAccessManager context)
{
if (!context.Database.Exists() || !context.Database.CompatibleWithModel(false))
{
var configuration = new DbMigrationsConfiguration();
var migrator = new DbMigrator(configuration);
migrator.Configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString, "System.Data.SqlClient");
var migrations = migrator.GetPendingMigrations();
if (migrations.Any())
{
var scriptor = new MigratorScriptingDecorator(migrator);
var script = scriptor.ScriptUpdate(null, migrations.Last());
if (!string.IsNullOrEmpty(script))
{
context.Database.ExecuteSqlCommand(script);
}
}
}
}
Ответ 2
Автоматическая миграция означает, что вам не нужно запускать команду add-migration
для ваших изменений в моделях, но вам нужно запустить команду update-database
вручную.
Если автоматическая миграция включена, когда вы вызываете update-database
, если в моделях ожидаются изменения, будет добавлена "автоматическая" миграция, и база данных будет обновлена.
Если вы хотите, чтобы ваша база данных обновлялась без необходимости вызова команды update-database
, вы можете добавить метод Database.SetInitializer(...)
в OnModelCreating()
в свой контекст, например:
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, MigrateDBConfiguration>());
}
...
}
public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<MyContext>
{
...
Обратите внимание, что вы должны объявлять DbMigrationsConfiguration
и MigrateDatabaseToLatestVersion
своим реальным контекстом, а не по умолчанию DbContext
.
Ответ 3
Если у вас есть изменения в ваших сущностях, сначала нужно запустить add-migration
, чтобы создать миграцию script.
После этого в Global.asax
вам нужно иметь такой код, как этот
var configuration = new MyProject.Configuration();
var migrator = new System.Data.Entity.Migrations.DbMigrator(configuration);
migrator.Update();
каждый раз, когда вы запускаете проект asp.net, он проверяет, есть ли у вас новая миграция для запуска и запускайте update-database
автоматически для вас.