13

TeamCity、NUnit、および Git との継続的な統合を使用しています。最近、FluentMigrator から Entity Framework Migrations に移行しました (しゃれを許してください)。私は主に、スキャフォールディング機能を利用するためにこれを行いました。

ただし、最初に変更をマイグレーションにスキャフォールディングしなくても、ソース管理にいくつかの変更をチェックインできる可能性があります (コミットしてコミットをプッシュする前にアプリケーションが実行されなかったシナリオを想像してください)。私は事前テスト済みのコミット ワークフローを使用しているため、migrate.exe を呼び出すまで待つのではなく、事前テストでこの問題を検出したいと考えています (ワークフローでは遅すぎて、「グリーン リポジトリ」が壊れてしまいます)。

私の質問は、移行モデルがコンテキスト モデルと一致しない場合を検出する単体/統合テストを作成して、移行を試みる前にビルドに失敗できるようにする方法です。データベースと一致しないことが予想されるため、テストからデータベースにアクセスしたくないことに注意してください。

私はこのアプローチを試しました:

    [Test]
    public void CheckWhetherEntityFrameworkMigrationsContextIsUpToDate()
    {
        Assert.DoesNotThrow(() =>
        {
            CallDatabase();
        });

    }

    private void CallDatabase()
    {
        using (var ctx = new MyContext("SERVER=(local);DATABASE=MyDatabase;Integrated Security=True;"))
        {
            var tenant = (from t in ctx.Tenant
                          select t).FirstOrDefault();
        }
    }

ただし、保留中の移行がある場合、これは常に失敗します(移行モデルがコンテキストモデルと同期していない場合ではなく、これが私が求めているものです)。

アップデート

この問題の EntityFramework プロジェクトに作業項目を追加しました。うまくいけば、彼らはこれを行う方法を追加することを検討します.

4

5 に答える 5

6

すべてのモデルの変更が移行に足場を組んでいるかどうかを確認するコードを次に示します。

bool HasPendingModelChanges()
{
    // NOTE: Using MigratorScriptingDecorator so changes won't be made to the database
    var migrationsConfiguration = new Migrations.Configuration();
    var migrator = new DbMigrator(migrationsConfiguration);
    var scriptingMigrator = new MigratorScriptingDecorator(migrator);

    try
    {
        // NOTE: Using InitialDatabase so history won't be read from the database
        scriptingMigrator.ScriptUpdate(DbMigrator.InitialDatabase, null);
    }
    catch (AutomaticMigrationsDisabledException)
    {
        return true;
    }

    return false;
}
于 2013-10-21T21:16:10.900 に答える
3

これは、Pablo Romeo のコードよりもうまく機能すると思います。これにより、ダウングレード スクリプトで欠落しているアイテムを検出するために、もう一度アップグレードしてからダウングレードします。

[TestFixture]
class MigrationTest
{
    [Test]
    public void RunAll()
    {
        var configuration = new Configuration();
        var migrator = new DbMigrator(configuration);

        // Retrieve migrations
        List<string> migrations = new List<string> {"0"};  // Not sure if "0" is more zero than the first item in list of local migrations
        migrations.AddRange(migrator.GetLocalMigrations());

        migrator.Update(migrations.First());

        // Doe een stapje naar voren, en een stapje terug (www.youtube.com/watch?v=2sg1KAxuWKI)
        // (Dutch pun) meaning: take a small step forward, and a small step back ;)
        for (int index = 0; index < migrations.Count; index++)
        {
            migrator.Update(migrations[index]);
            if (index > 0)
                migrator.Update(migrations[index - 1]);
        }

        migrator.Update(migrations.Last());

        migrator.Update(migrations.First());
    }
}
于 2015-04-26T20:19:14.880 に答える