3

我们有我们的迁移,并且我们有一个在每次迁移运行后执行的种子方法。

如果种子方法失败,我可以回滚种子数据,但我还想在代码中回滚“update-database”语句以将数据库结构恢复到之前的状态。

这可能吗?

一些代码:

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;
            }
    }
}
4

1 回答 1

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

于 2013-02-06T10:25:53.357 回答