実行時にEntity Framework Code Firstの列マッピングを表示する方法はありますか?

Entity Framework Code Firstにアドオンを書き込もうとしています。実行時にモデル列の設定を取得する方法が必要です。たとえば、これは DbModelBuilder OnModelCreating のコード設定です。

builder.Entity()
    .Property(n => n.ReportsToID).HasColumnName("ReportsTo");

これが完了すると、EntityFrameworkは自分のプロパティの名前がテーブルの列名と異なることを認識しますが、 "ReportsTo" という文字列が自分自身で ReportsToID 実行時に?理想的には、次のようなメソッドを記述しようとしています。

public string GetMappedColumnName(DbContext context, 
    Func selector);

どのように使用されるでしょう:

string mappedColumnName = GetMappedColumnName(context, 
    x => x.ReportsToID);

私はDbContext内のマップされた列名をどこで見つけるか分かりません。彼らもアクセス可能ですか?

5
解決策(多少)がここにあります: stackoverflow.com/a/20807366/861716
追加された 著者 Gert Arnold,
私はあなたの実際の解決策を見て非常に興味があります。別の回答として投稿できますか?それは私にとって非常に役立つでしょう。
追加された 著者 STW,
私は同様の問題を抱えていたここに私の解決策です: stackoverflow.com/questions/7008212/…
追加された 著者 maxlego,

1 答え

理論的にはそうです。実際には、簡単なテストでは実行時にこれらの情報を取得できないため、デバッガで表示されますが、使用する必要があるタイプはエンティティフレームワークの内部にあるため、取得できません。

理論。すべてのマッピング情報は、実行時には利用できますが、リフレクションでは使用できません。これらのクラスは、直接使用するようには設計されていない MetadataWorkspace クラスのインスタンスに格納されます。このクラスとのあらゆる対話では、必要なデータを取得する方法を見つける前にデバッガで時間を費やす必要があります。このデータはDbContext APIからアクセスできません。 DbContext ObjectContext に変換して MetadataWorkspace にアクセスする必要があります。

ObjectContext objContext = ((IObjectContextAdapter)dbContext).ObjectContext;
GlobalItem storageMapping = objContext.MetadataWorkspace.GetItem("NameOfYourContextClass", DataSpace.CSSpace);

storageMapping 内部 System.Data.Mapping.StorageEntityContainerMapping クラスのインスタンスです。私が理解しているように、このクラスは、ストレージと概念モデルの間のMSL =マッピングのランタイム表現でなければなりません。

デバッガを使用すると、インスタンスを調べることができます。また、プロパティと列(かなり深いネストされたもの)間のマッピングに関する情報が得られますので、リフレクションを使用して取得することもできますが、どんな.NETフレームワークのパッチ/修正/アップデートでもアプリケーションが壊れる可能性があります。

4
追加された
@セバスチャン:これはADO.NETチームの質問です。私はなぜそれが非常に複雑ですが、それはMS APIが通常働く方法であると答えることができません - 彼らは内部的に複雑で、元々はMSが想定していなかった拡張に閉じています。
追加された 著者 Ladislav Mrnka,
一度 GlobalItem エントリポイントを取得したら、残りは簡単でした。ありがとう。
追加された 著者 GenericTypeTea,
なぜこの情報を入手するのはとても複雑ですか? EFはバルクインサートの性能に関しては本当に悪いです。カスタムEntityDataReaderとSqlBulkCopyを使用すると、これらのマッピングがある場合にのみ、ジョブを終了できます。これらのマッピングの1つが変更されたときに手動で修正する必要があるため、これらのマッピングを何度もハードコーディングする必要はありません。わかった、OR/Mはバルクデータではない。しかし、一括挿入が必要な他のシステムからのインポートを検討してください。今何?
追加された 著者 Sebastian Weber,
列名にアクセスするためのパスを指定することは可能でしょうか?表示されるのは、オブジェクトのプロパティ名であり、列名ではありません
追加された 著者 Cedric Dumont,
実際にこの投稿は、efでマップされた列の名前を取得するのに役立ちました:>> stackoverflow.com/questions/20161854/…
追加された 著者 Cedric Dumont,