2

データベース モデル (「 context 」と呼ばれることもあります) は、インストールされているサービスやプラグインに基づいて、起動時に動的に組み立てられます。DbContext.OnModelCreatingプラグインとサービスは、IoC コンテナーを介してモデル定義フラグメントをエクスポートし、メソッドが呼び出されると、アプリケーション コアがそれらを取得して実行します。

問題は、このセットアップで Code First Migrations を使用できますか (また、その方法を教えてください) ?
(以下は、私が試したことと特定の問題についての詳細です)

私の以前のプロジェクトでは、データベースは古いコードから継承されていたため、とにかく Code First のデータベース生成機能を使用できませんでした。単純にデルタ スクリプトの長い行を保持し、デプロイ時に手動で実行しました (単一ホストの種類のプロジェクトでした)。

今、私は新しいプロジェクトを開始しています。今回は、データベースが真新しく、Code First で遊ぶ準備ができています。当初、私は Code First Migrations に興奮していました。実際にやってみるまでは。DbContext私のプロジェクトで明示的に定義された が存在しないため、最初の試みは明らかに失敗しました。

これまでのところ、実行可能な唯一のオプションは手動で移行をコーディングすることであると思われますが、私は完全に問題ありません。ただし、これは から継承されたいくつかのクラスを作成するだけの単純なものではないことがわかりDbMigrationます。

小さなテスト プロジェクトでいくつかの実験を行った後、移行自動生成機能が の実装を追加することがわかりましたIMigrationMetadata。これには、とりわけ、SourceおよびTargetプロパティの値としてモデルのハッシュが含まれています。おそらく、このハッシュは、データベースの「現在の」状態 (__MigrationHistoryテーブルに記録されている) からコード内のモデルによって定義されている最新の状態への移行全体のパスを識別するために使用されます。これは完全に理にかなっていますが...

当然のことながら、モデルのハッシュをどこで取得すればよいかわかりません。そのIMigrationMetadataため、移行に実装できません。

一方、メタデータ インターフェイスはDbMigrationクラス自体に含まれていないことがわかります。これは、オプションである可能性があると考えさせられます。したがって、移行は実際にはハッシュ値がなくても機能することがわかりますが、問題は、どのように?

私がインターネットで見つけたすべての情報は、単純で非常に基本的なチュートリアルです。移行を手動で作成する方法 (およびそれがサポートされているかどうか) に関する情報はありません。実際の動作方法と拡張方法に関するドキュメントはありません。そして、それは外からはまったくわかりません。
この時点で ILSpy に頼る準備ができていますが、EF 全体が非常に複雑であるため、妥当な時間内に必要なものを見つけることができないのではないかと心配しています。

4

2 に答える 2

0

プロジェクトを実行すると、データベースに追加のテーブルが作成されます。

              EdmMetadata table

ハッシュは常に、EdmMetadata エンティティと現在のコード ファースト モデルの助けを借りて作成されます。これは、データベースの EdmMetadata テーブルに格納されている SHA-256 ハッシュです。そのテーブルからそれを得ることができます。

従うべき方法論は次のとおりです。

  1. を使用して現在のモデルのハッシュを取得します

              var hash=GetModelHash(OldContext);
    
  2. を使用して、コード内のモデル (新しいモデル) がデータベース内のモデル (古いモデル) と互換性があるかどうかを確認します。

               CompatibleWithModel(hash,CurrentContext,ObjectContext)
    

このメソッドはboolを返します。

  1. 互換性がない場合は、データベース内の既存のテーブルを削除してください。

  2. 新しいテーブルを作成する

  3. 現在のハッシュをデータベースに保存します

  4. データをシードします。

コードは次のようになります。

                {
                        var objectContext = ((IObjectContextAdapter)context).ObjectContext;
                        var modelHash = GetModelHash(objectContext);
                        if (CompatibleWithModel(modelHash, context, objectContext))
                            return;
                        DeleteExistingTables(objectContext);
                        CreateTables(objectContext);
                        SaveModelHashToDatabase(context, modelHash, objectContext);
                        SeedData(context);
                }

必ずクラスを継承してください

    IDatabaseInitializer<T> where T:DbContext
于 2012-11-22T19:22:18.820 に答える