实体框架代码优先:触发特定迁移

时间:2014-08-29 12:02:55

标签: entity-framework ef-code-first ef-migrations

假设我定义了第一个迁移类的随机代码:

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

无论当前的数据模型如何,我如何执行它。 我可以通过代码或powershell强制执行此迁移吗?

1 个答案:

答案 0 :(得分:1)

迁移始终与基础上下文和模型建立连接。这基本上是__MigrationHistory表的内容。

因此,使用默认的DbMigrator,如果没有Context,则无法执行migraton。

但您可以使用Reflection从自定义Migration获取内部“Operations”属性,将其手动传递给MigrationSqlGenerator并手动执行语句。

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