2014-08-29 106 views
0

讓說我有定義的隨機碼第一遷移類:實體框架代碼首先:觸發特定遷移

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

遷移始終與底層的上下文和模型有關。這基本上是__MigrationHistory表的內容。

所以使用默認的DbMigrator,不可能在沒有Context的情況下執行migraton。

但您可以使用Reflection從您的自定義遷移中獲取內部「操作」屬性,將其手動傳遞給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(); 
    } 
}