2017-04-07 15 views
0

EF 6.1.3。複合外部キーを使用したEntity Frameworkナビゲーションプロパティ

"Header/Item"タイプのパターンの多くのインスタンスを含むドメインがあります。ここでは、ヘッダーには多数のアイテム(1対多)があり、 "最新"または "最新"アイテムがあります。次のように

これが表現されます。

Header 
    Guid Id 
    Guid CurrentItemId 
    Item CurrentItem 
    ICollection<Item> AllItems 

Item 
    HeaderId 
    Id 

アイテムのPKは常にHeaderID +アイテムIDです。その理由は、アイテムの最も一般的なアクセスパターンは、特定のヘッダーに関連するすべてのアイテムをリストすることであり、HeaderIDをPK /クラスタード・インデックスの最初の部分とすることは、クラスタード・インデックスのシークでそのデータを取得することを意味します。

私たちがCurrentItemナビゲーションプロパティを使用すると、ItemIDを使用してルックアップを実行するだけで、結果的には素晴らしいクエリプランにはならないという問題があります。

これは、私たちがCurrentItemを使用してCurrentItemをルックアップするための規約であると考えています。私の質問は、私がEFに、Header.Id、Header.CurrentItemId - > Item.HeaderId、Item.Idをマッピングすることによって、常にCurrentItemの結合を実行するように指示する方法ですか?

私は、これは、ここで説明したものよりもわずかに異なるシナリオであると考えている:私の場合はcomposite key as foreign key

、私は1対1のマッピングは、1人のトップの多く持っていない、とWithforeignKey方法があるようには思えませんそのシナリオで利用可能です。

+0

[複合キーとしての複合キーの可能な重複](http://stackoverflow.com/questions/5436731/composite-key-as-foreign-key) – niksofteng

+0

私は投稿と重複しているかどうかはわかりません参照はエンティティ間で列の不一致がありません。私の場合、HeaderのIDフィールドは、ItemエンティティのIDフィールドにマッピングされているCurrentVersionIDフィールドに加えて、Item.HeaderIdフィールドにマップする必要があります。これは1対1のマッピングでもなく、1対多のマッピングでもあり、ItemエンティティにはHeaderに戻るnavプロパティはありません。 これは小さな違いかもしれませんが、それは私を踏みにじっています。 – RMD

+0

私は、仕事をしているのにIntegersを使用していて、この問題はありません。私は、EFがguidを異なって扱っているかもしれないと思っています。あるいは、テーブルにユニークな制約がある場合、それを使用しようとしています。 また、guidによってフラグメンテーションにいくつかの問題が発生する可能性がありますが、SQL Serverでこの問題が発生しています。 –

答えて

0

私たちが望むようにEFを生成することができなくなったため、dbコマンドインターセプタを作成して、この結合のインスタンスを動的に検索し、設計した複合キーに一致するように再書き込みします。

我々はそうのようなDbContextレベルとしてこれを設定:

this.ModifyJoin<Item, Header>(
     (i) => new Header() { CurrentItemId = i.Id }, //What to find 
     (i) => new Header() { CurerntItemId = i.Id, Id = i.HeaderId }); //What to replace with 

この情報は、コンテキストインスタンス自体に装着され、コマンドのインターセプタがオーバーライドを見ているときに、それはSQLを再書き込みするためにそれらを使用しています。

これはほとんどのシナリオでうまくいきますが、LINQステートメントの一部としてItemテーブルで追加のフィルタリングを行っているときや、EFで使用されているエイリアシングルールが複雑すぎて書かずにフォローできない場合完全なSQLパーサー。

私たちの使用のためには、これは時間の約90%の理想的な参加となり、私たちのために十分です。

これを行うためのコードは難しくありませんが、ここに入れるには大きすぎます。コピーが必要な場合はコメントを追加し、GitHubに載せます。

関連する問題