我们进行了迁移,并且我们有一个种子方法,可以在每次迁移后执行。
如果种子方法失败,我可以回滚种子数据,但我也希望在代码中回滚“update-database”语句,将db结构恢复到之前的状态。
这可能吗?
一些代码:
internal sealed class Configuration : DbMigrationsConfiguration<TheContext>
{
protected override void Seed(TheContext context)
{
//Set a bunch of entities
using (var transaction = new TransactionScope())
{
try
{
context.SaveChanges();
transaction.Complete();
}
catch (Exception ex)
{
//TODO: How do I rollback the last Update-Database command?
throw;
}
}
}
答案 0 :(得分:0)
我对像您这样的案例的建议,即您拥有影响迁移成功的数据,是在迁移过程中进行的。
我一直这样做,创建要在迁移的Up方法和down方法中运行的sql脚本。这样,当迁移成功应用时,您也知道它与数据一致。另外,您可以撤消迁移,同时撤消所有数据。
这种方法的缺点是你不能使用EF的上下文来创建数据,迫使你创建运行你手工制作的句子的Sql方法。
public class TestMigration() : DbMigration
{
protected override Up()
{
//Do some migration stuff
Sql("INSERT YOUR DATA HERE");
}
protected override Down()
{
//Undo some migration stuff
Sql("DELETE YOUR DATA HERE");
}
}
如果您仍想使用Seed方法,我自己也没有尝试过,但我认为这可行:
internal sealed class Configuration : DbMigrationsConfiguration<TheContext>
{
protected override void Seed(TheContext context)
{
//Set a bunch of entities
using (var transaction = new TransactionScope())
{
try
{
context.SaveChanges();
transaction.Complete();
}
catch (Exception ex)
{
var migrator = new DbMigrator(this);
var lastMigration = migrator.GetDatabaseMigrations().Last();
migrator.Update(lastMigration);
}
}
}
我可以看到这个代码的问题是,在运行Update方法之后,Seed方法将再次触发,创建一个无限循环。