假设我定义了第一个迁移类的随机代码:
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强制执行此迁移吗?
答案 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();
}
}