Proviste
Proviste

Reputation: 177

Entity framework Code First : trigger specific migration

Let say I have a random code first migration class defined :

public partial class t2 : DbMigration
{
    public override void Up()
    {
        RenameTable(name: "dbo.EntityC", newName: "EntityCs");
        DropTable("dbo.EntityA");
        DropTable("dbo.EntityB");
    }

    public override void Down()
    {
        CreateTable(
            "dbo.EntityB",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    StringOtherProperty = c.String(),
                })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "dbo.EntityA",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    StringProperty = c.String(),
                })
            .PrimaryKey(t => t.Id);

        RenameTable(name: "dbo.EntityCs", newName: "EntityC");
    }
}

How can I execute it, regardless of the current data model. Can I, by code or powershell, force the execution of this migration ?

Upvotes: 0

Views: 189

Answers (1)

codeworx
codeworx

Reputation: 2745

A migration always has a connection to the underlying context and model. That is basically the content of the __MigrationHistory Table.

So with the default DbMigrator it is not possible to execute a migraton without a Context.

But you could use Reflection to get the internal “Operations” property from you custom Migration, pass it manually to the MigrationSqlGenerator and execute the Statements by hand.

SqlServerMigrationSqlGenerator gen = new SqlServerMigrationSqlGenerator();
IEnumerable<MigrationOperation> operations;

var migration = new MyMigration();
migration.Up();

var property = typeof(DbMigration)
    .GetProperty("Operations", BindingFlags.Instance | BindingFlags.NonPublic);

operations = property.GetGetMethod(true)
    .Invoke(migration, null) as IEnumerable<MigrationOperation>;

if (operations != null) {
    var statements = gen.Generate(operations, "2012");

    using (var scope = new TransactionScope()) {
        var connection = new SqlConnection("Data Source=.;Initial Catalog=MigrationTest;Integrated Security=True;");
        connection.Open();
        foreach (var item in statements) {
            var command = connection.CreateCommand();
            command.CommandText = item.Sql;
            command.ExecuteNonQuery();
        }
        scope.Complete();
    }
}

Upvotes: 1

Related Questions