2013-02-06 10 views
15

Linqを使用してナビゲーションプロパティを関連エンティティのサブセットにフィルタリングする方法を知りたい。EntityFramework 5含まれているナビゲーションプロパティをフィルタリングする

query.Where(x => x.Users.Any(y => y.ID == actingUser.ID)) 
    .Select(x => new 
    { 
     Event = x, 
     Discussions = x.Discussions.Where(actingUser.GenerateSecurityFilterFor<Domain.Discussion>()) 
    }) 
    .OrderBy(x => x.Discussions.Count()) 
    .ThenBy(x => x.Event.Name); 

しかし、これが原因私たちのクエリー生成の一般的な性質のために理想的なよりも大幅に少ないですし、投げる場合も大幅に恐ろしいSQLクエリを生成する:私は、次のような匿名のセレクタを行うことをお勧めこのテーマの周りのすべての答えを知っていますプロファイラ。

私のような何かを達成できるようにしたいと思います:

query.Include(x => x.Discussions.Where(actingUser.GenerateSecurityFilterFor<Domain.Discussion>())) 
     .OrderBy(x => x.Discussions.Count()) 
     .ThenBy(x => x.Name); 

が、私はこれはEF5(またはそのことについては任意のバージョン)でサポートされていないことを認識したが制約達成する方法がなければなりませんLinqを介して匿名型のselect文を掘り下げずに結果を設定します。

私はの曲に何かをしようとしている:あなたはラムダ式内で割り当てを持っており、ここで匿名型を選択することはできませんしかし

query.GroupJoin(discquqery, 
    x => x.ID, 
    x => x.Event.ID, 
    (evt, disc) => evt.Discussions = disc.Where(actingUser.GenerateSecurityFilterFor<Domain.Discussion>())).ToList(); 

は、それが選択を使用して行うのと同じジレンマを引き起こします。

SELECT 
    --Properties 
FROM Event e 
LEFT OUTER JOIN Discussions d 
    ON e.ID = d.EventID AND --Additional constraints 
WHERE 
    --Where conditions 
ORDER BY 
    --Order Conditions 

をそれを行うための方法がなければならないSQLに参加制約するように簡単です:

私はEFは(私が見つけることができること)を生成する方法を提供していない理由を私は理解することができないと思いますそれもLinqを通じて。

PS:スタック、MSDN、エキスパートエクスチェンジなどを検索しました。これは重複していないことを認識してください。この対象に触れることさえあれば、 "それはできない"という答えを出すか、まったく答えないかのいずれかがあります。これを含めて何も不可能ではありません。

+1

まあ、ここでは "それを行う"答えです:http://stackoverflow.com/a/13904825/861716 –

+5

EFでクエリ生成エンジンを拡張する方法があります。したがって、これは不可能ではなく、それが唯一のルートであれば、答えはEFクエリエンジンの拡張であり、INNER/OUTER JOINに追加のフィルタを含めることができます。何もできません...もし私がEFを再コンパイルする必要があれば、私はそうするでしょう...既存の答えを持たないということは、答えがあなた自身で構築されていることを意味します(現在、私は質問していても、やっています) – VulgarBinary

+4

精神!! –

答えて

8

この件でも触れているものは、「 できません」という回答があるか、まったく回答がありません。不可能なものは何もない... これを含む。

確かに。可能です。 EFソースコードをダウンロードして、この機能を自分で追加することができます。オープンソースプロジェクトとコミュニティに大きな貢献をするでしょう。私はEFチームが喜んであなたの努力のお手伝いをすると信じています。

現在のバージョンでは「実行できません」is the answerです。質問の冒頭で説明したように、匿名または特殊なマッピングされていないタイプへの投影を使用できます。他のオプションは、すべての親に対して関連するエンティティをロードするために、単一の親または別のクエリに対して関連するエンティティをロードするための別個の明示的なクエリです。単一の親のための

負荷の関係:すべての親のための

context.Entry(event) 
     .Collection(e => e.Discussions) 
     .Query() 
     .Where(d => ...) 
     .Load(); 

負荷の関係(オフに遅延ロードが必要です):

// load all parents 
var events = query.Where(e => ...).ToList(); 

// load child filtered by same condition for parents and new condition for children 
childQuery.Where(d => e.Event ... && d.Something ...).Load(); 

第二の溶液をバックにナビゲーションプロパティを持っている子が必要ですparent(最初に親をロードするために使用された同じクエリ条件を構築するため)。すべてが正しく設定され、エンティティが添付されている場合、EFは親エンティティ内のリレーション(コレクション)を自動的に修正する必要があります(ダイナミックプロキシのコレクションにはロードされていないので、遅延ロードと一緒に使用することはできません)。

+0

それから明らかに私はEF5コアを拡張しています。 DLL全体を変更して再コンパイルする代わりに、拡張する方法があるかどうか知っていますか? – VulgarBinary

+1

DLLを再コンパイルする必要があります。あなたは[EF codeplex site](http://entityframework.codeplex.com/discussions)にアクセスして、この貢献をEFチームと直接話し合うことができます - 彼らはこの機能のためのいくつかのハイレベルなデザインをすでに持ち、あなたと共有しているかもしれません。 –

+3

フィルタリング対象に投票する[ここをクリック](https://entityframework.codeplex.com/workitem/47)! – Chris

関連する問題