1

私が問題を抱えているシナリオは次のとおりです。

  1. EF 4.1を使用して作成されたコードファーストモデルと、生成された対応するデータベース
  2. EFが4.3.1にアップグレードされ、移行が追加され(モデルが変更されていないため、IgnoreChangesを使用)、移行の使用を開始します(__MigrtionHistoryテーブルが作成され、EdmMetadataが削除されました)-「InitialMigration」と呼びましょう
  3. モデルが変更され、新しいプロパティが追加され、対応する列を追加する移行が生成され(これを「NewPropertyMigration」と呼びます)、Devデータベースに適用されます(Migrate ToLatest初期化戦略のバージョンを使用)
  4. コードが本番環境にプロモートされると、データベースは期待どおりに新しい列で更新されます
  5. 次に、新しいデータベースがDevで作成され、最新のモデルに基づいているため、作成直後に新しい列が含まれますが、初期化戦略を実行すると、「InitialMigration」と「NewPropertyMigration」は保留中として検出されますが、 EdmMetadataが存在しないため、削除するものがなく、新しい列がすでに存在するため、両方とも失敗します。追加できません。

この新しいデータベースの__MigrationHistoryテーブルを確認すると、「InitialCreate」エントリのみが含まれているため、他の2つの移行が保留中と見なされる理由が説明されます。しかし、適用せずにこのテーブルに入る方法がわかりません。同時に、データベースにはすでに適用される変更が含まれているため、実際に適用する必要はありません。私は何が欠けていますか?

同じモデルを表しているにもかかわらず、「InitialCreate」の「Model」列が「NewPropertyMigration」の「Model」列と異なるのは少し疑わしいようです。それが原因でしょうか?

更新:これは、新しいデータベースを作成し、同時に移行を自動的に適用するために使用するコードです

public class MigratePaymentsToLatestVersion<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
{
public void InitializeDatabase(TContext context)
{
    // Create a brand new database if it doesn't exist but still apply any pending migrations
    context.Database.CreateIfNotExists();
    var migrator = new DbMigrator(configuration);
    migrator.Update();
}
}

更新2:同じ問題を示すより単純なシナリオ

これをさらに調査している間、私は以下に説明するはるかに単純なシナリオで動作を再現することができました。

  1. シンプルなモデルとコンテキストを作成する
  2. テストアプリケーションで、1つのエンティティを追加します-すべてのデフォルト設定でデータベースが自動的に作成され、オブジェクトが追加されます
  3. 移行を有効にする-'InitialCreate'移行が生成されます
  4. Update-Database-'InitialCreation'はすでに__MigrationHistoryにあるため、コマンドは保留中の移行を返しません
  5. データベースを削除してテストアプリケーションを再実行します-データベースは自動的に再作成されます
  6. この時点では、「InitialCreation」の移行は保留中と見なされるため、追加の移行を追加したり、update-databaseを実行したりすることはできませんが、すべてのエンティティがすでに存在するため、適用できません。
4

1 に答える 1

2

私は今それを分類しました。私が見逃していた重要な部分は、4.1から4.3への移行方法に関連しているようです。私はef-4-3-migrations-and-existing-databaseからの手順に従っています。うまくいくように見えるのは、SOの質問how-to-use-migrations-on-an-existing-dbで説明されている手順です。。両方を比較すると、最初の移行(「InitialMigration」と呼ばれる)を行うときに一方が-IgnoreChangesに依存し、もう一方がその時点でのモデル全体を含む完全な「InitialCreate」移行を作成することがわかります。後者のアプローチの2つの重要な結果は次のとおりです。-新しいデータベースを作成する場合、モデルの完全な定義を含むInitialCreate移行を使用して、「他のコード」の代わりにデータベースを作成します(正確にはわかりませんが、これが一部であると推測します)これは、移行が有効になっていない場合に必要です)モデルに基づいてデータベースを生成します-新しいデータベースは、最新のモデルと__MigrationHistoryにリストされているすべての移行で作成されます

したがって、InitialCreateアプローチを使用すると、既存のデータベースに移行を適用でき(履歴のエントリが手順の一部として手動で追加されるため、InitialCreateはスキップされます)、同時に新しいデータベースを作成できます。モデルとデータベースが非同期であるというエラーを取得せずに、それらに新しい移行を追加します。

私のように、最初の手順に従った人々に役立つことを願っています。

于 2012-07-24T10:49:34.217 に答える