Entity Framework, Automatic apply Migrations

2019-01-21 23:56发布

I use Entity Framework code first and set AutomaticMigrationsEnabled true by this code :

Database.SetInitializer(new MigrateDatabaseToLatestVersion<DbContext, MigrateDBConfiguration>());
//////////////////////////////////

public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<DbContext>
{
    public MigrateDBConfiguration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = true;
    }
}

In first run the project it work fine and create database and tables. after I change model and drop some field or add new fields and run Add-Migration, Migration class generated but after run project this exception occur :

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code

Additional information: The model backing the 'DBContext' context has changed since the database was created.

EDIT: Like answer of arturo menchaca I change may code like this :

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

...

But ths exception is ocure :

There is already an object named 'MyTable' in the database.

I want apply my migration.

3条回答
Animai°情兽
2楼-- · 2019-01-22 00:46

Finally I found a solution to my problem. I call this method in each application start :

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);
            }
        }
    }
}
查看更多
你好瞎i
3楼-- · 2019-01-22 00:54

If you have change in your entities, you need first run add-migration to create the migration script.

After that in your Global.asax

you need to have some code like this

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

        migrator.Update();

every time that you run your asp.net project it'll check if you have a new migration to run and run update-database automatically for you.

查看更多
放荡不羁爱自由
4楼-- · 2019-01-22 00:57

Automatic Migrations means that you don't need to run add-migration command for your changes in the models, but you have to run update-database command manually.

If Automatic Migrations is enabled when you call update-database, if there are pending changes in your models, an 'automatic' migration will be added and database will be updated.

If you want that your database is updated without need to call update-database command, you can add Database.SetInitializer(...) in OnModelCreating() method on your context, like so:

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>
{
    ...

Note that you should declare DbMigrationsConfiguration and MigrateDatabaseToLatestVersion with your real context, not the default DbContext.

查看更多
登录 后发表回答