2011-03-09 13 views
4

基本的に、私は複数のテーブルのデータを集約して単一のテーブルに結合したレポートタイプのクエリを作成しています。Linq to SQL:グループ化されたセットを結合すると、クロス適用/外部適用が行われます。

それは少し次のようになります。

var docs = from x in DB.Docs 
      group x by x.PersonId into g 
      select new { 
       g.Key, 
       totalSent = g.Sum(x => x.SentDate.HasValue ? 1 : 0), 
       lastSent = g.Max(x => x.SentDate) 
       ... 
      }; 

var summary = from x in DB.People 
       from y in docs.Where(y => y.Key == x.Id).DefaultIfEmpty() 
       select new { 
        x.Id, 
        x.Name, 
        y.totalSent, 
        y.lastSent 
       } 

私はこれがdocsの結果にDB.Peopleに参加しましたが、代わりに、私はいくつかのクレイジーCROSS APPLY((SELECT NULL AS [EMPTY]) as [t1] OUTER APPLY ...のものを得る左のSQLを作成することを期待します。

私は考えることができる左の結合構文のすべての変種を試しました。私はdocsを別のクエリーにラップしても、同じことが起こります。

私には何が欠けていますか?

+0

あなたが望む結果を取得されていません

はおそらく、あなたが参加するためのもの? 「CROSS APPLY」は狂っているように思えるかもしれませんが、LINQ to SQLはSQLよりも賢くて、結果が正しいとすればそのことをやります。 – shaunmartin

+1

結果は決して戻ってこない...「OUTER APPLY」は基本的に私のグループ化されたセットを 'DB.People'の各行のテーブル値関数にします。クエリがタイムアウトします。 –

答えて

0
from x in DB.People 
from y in docs.Where(y => y.Key == x.Id).DefaultIfEmpty() 

上記は明らかにデカルト結果を生成し、後にフィルタリングされます。

from x in DB.People 
join y2 in docs on x.Id equals y2.Key into g 
from y in g.DefaultIfEmpty() 

をこれについてどのように:

from x in DB.People 
let g = x.Docs 
select new 
{ 
    x.Id, 
    x.Name, 
    totalSent = g.Sum(y => y.SentDate.HasValue ? 1 : 0), 
    lastSent = g.Max(y => y.SentDate) 
} 
+0

私のバージョンはショートカットです。もし 'docs'がグループ化されたセットを表していなければ、それは左の結合を作成します。 –

+0

私のアプローチで同じSQLを取得できますか? –

+0

ええ、どちらの方法でも同じSQLが得られます。 2番目の例は残念なことに、これらは直接的なL2Sマッピングを持つやや難しいデータベースアーキテクチャの上に構築されたPOCOオブジェクトであり、変更する時間がないため動作しません。たとえば、ドキュメントは3つのテーブルに対して非常に興味深いクエリを表します。 –

関連する問題