Entity Framework, автоматическое применение миграции

сначала я использую код Entity Framework и устанавливаю 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 создается класс миграции, но после запуска проекта это исключение:

исключение типа System.InvalidOperationException ' произошло в EntityFramework.dll, но не был обработан в user код

дополнительная информация: модель, поддерживающая контекст "DBContext", имеет изменилась с момента создания базы данных.

EDIT: как ответ Артуро Менчака я могу изменить код, как это:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<DBContext, MigrateDBConfiguration<DBContext>>());

...

но THS исключение ocure:

в базе данных уже есть объект с именем "MyTable".

Я хочу применить мою миграцию.

3 ответов


Автоматические Миграции означает, что вам не нужно работать add-migration команда для ваших изменений в моделях, но вы должны запустить вручную.

если Автоматические Миграции включен при вызове 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.


наконец-то я нашел решение своей проблемы. Я вызываю этот метод в каждом запуске приложения:

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);
            }
        }
    }
}

если у вас есть изменения в ваших сущностях, вам нужно сначала запустить add-migration для создания сценария миграции.

после этого в Global.asax

вам нужно иметь такой код, как этот

        var configuration = new MyProject.Configuration();
        var migrator = new System.Data.Entity.Migrations.DbMigrator(configuration);            

        migrator.Update();

каждый раз, когда вы запускаете asp.net проект он проверит, есть ли у вас новая миграция для запуска и запуска update-database автоматически для вас.