2011-03-09 52 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 
       } 

我希望,這創造了左加入DB.Peopledocs的結果,而是我得到一些瘋狂的東西CROSS APPLY((SELECT NULL AS [EMPTY]) as [t1] OUTER APPLY ... SQL。

我試過左連接語法的每個變體,我可以想到,我甚至在另一個查詢中包裝了docs,並且我得到了同樣的結果。

我缺少什麼?

+0

你沒有得到你想要的結果? 'CROSS APPLY'可能看起來很瘋狂,但就我的經驗而言,LINQ to SQL通常比我用SQL更聰明,我只是讓它做它的事情......如果結果是正確的。 – shaunmartin 2011-03-09 19:41:47

+1

結果永遠不會回來......'OUTER APPLY'基本上使得我的分組集合成爲'DB.People'每行的表值函數。查詢超時。 – 2011-03-09 20:43:33

回答

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'不代表分組集合,它會創建一個左連接。 – 2011-03-09 22:26:43

+0

所以你用我的方法得到相同的SQL? – 2011-03-09 23:27:10

+0

是的,這兩種方法讓你相同的SQL。第二個例子不能工作,因爲這些POCO對象是建立在具有直接L2S映射的有些笨重的數據庫架構之上的,所以我沒有時間去改變。例如,Docs對3個表格表示相當有趣的查詢。 – 2011-03-09 23:48:32