3

移行があり、移行が実行されるたびに実行されるシード メソッドがあります。

シード メソッドが失敗した場合は、シード データをロールバックできますが、コードで "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;
            }
    }
}
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 に答える