Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually call DbMigration.Up in EF

I want to be able to Up() method of a migration manually. Currently I'm trying to do that but calling that contains CreateTable method does not create the table. I suspect that connection is not properly set. And there are no properties to set it.

I also tried DbMigrator but it calls some internal EF migration methods.

So does anyone know how to set a connection to be used by DbMigration.Up method?

Thanks in advance!

like image 421
Dmytro I. Avatar asked Aug 26 '13 13:08

Dmytro I.


People also ask

How do I run an existing migration in Entity Framework?

Run the Add-Migration InitialCreate command in Package Manager Console. This creates a migration to create the existing schema. Comment out all code in the Up method of the newly created migration. This will allow us to 'apply' the migration to the local database without trying to recreate all the tables etc.

What is up and down in migration?

The up method is called when migrating “up” the database – forward in time – while the down method is called when migrating “down” the database – or, back in time. In other words, the up method is a set of directions for running a migration, while the down method is a set of instructions for reverting a migration.


2 Answers

I use the following code to explicitly be able to upgrade my database in the Application_Start event:

var config = new MyDatabaseMigrationsConfiguration();
var migrator = new System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator(new System.Data.Entity.Migrations.DbMigrator(config), new MyCommonMigrationsLogger());
if (migrator.GetPendingMigrations().Any())
{
  migrator.Update();
}

As far as i know this will use the default (named) connectionstring from my DatabaseContext to apply the pending changes.

  • You can specify the TargetMigration in the migrator.Update() if you want to be explicit
  • The MyCommonMigrationsLogger is just a simple Logging.Common implementation for the System.Data.Entity.Migrations.Infrastructure.MigrationsLogger
like image 154
Mark van Straten Avatar answered Sep 19 '22 21:09

Mark van Straten


For complete manual control over migrations, you can use the following extension method:

public static void RunMigration(this DbContext context, DbMigration migration)
{            
    var prop = migration.GetType().GetProperty("Operations", BindingFlags.NonPublic | BindingFlags.Instance);
    if (prop != null)
    {
        IEnumerable<MigrationOperation> operations = prop.GetValue(migration) as IEnumerable<MigrationOperation>;
        var generator = new SqlServerMigrationSqlGenerator();
        var statements = generator.Generate(operations, "2008");
        foreach (MigrationStatement item in statements)
            context.Database.ExecuteSqlCommand(item.Sql);
    }
}

Example: Having a migration like this:

public class CreateIndexOnContactCodeMigration : DbMigration
{
    public override void Up()
    {
        this.CreateIndex("Contacts", "Code");
    }

    public override void Down()
    {
        base.Down();
        this.DropIndex("Contacts", "Code");
    }
}

You could run it against your DbContext:

using (var dbCrm = new CrmDbContext(connectionString))
{
    var migration = new CreateIndexOnContactCodeMigration();
    migration.Up(); // or migration.Down();                
    dbCrm.RunMigration(migration);
}
like image 30
Panos Roditakis Avatar answered Sep 20 '22 21:09

Panos Roditakis