EF:当种子失败时,如何回滚更新数据库迁移?

时间:2013-01-22 19:58:12

标签: .net-4.0 entity-framework-5

我们进行了迁移,并且我们有一个种子方法,可以在每次迁移后执行。

如果种子方法失败,我可以回滚种子数据,但我也希望在代码中回滚“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;
            }
    }
}

1 个答案:

答案 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方法将再次触发,创建一个无限循环。