2010-08-16 67 views
1

我需要在C#中編寫該方法,該方法將從數據庫返回一些特定的字典。讓說,存儲在2個表中的數據是這樣的:lambda表達式 - 相當於sql外部連接

表組(ID,姓名):

1, 'Management' 
2, 'IT Department' 
3, 'Production' 

的用戶(ID,姓名,的groupId,專案編號):

1, 'John', 1, 1 
2, 'Ben', 2, 1 

現在我需要檢查在每個項目中,每個組都有不少於一個用戶。 SQL查詢來實現這個信息將是:

declare @projectId int; 
set @projectId = 1; 

select g.Name, case when(isnull(u.id,0) > 0) then 1 else 0 end HasUsers 
from groups g 
left join users u 
on g.id = u.groupId and u.projectId = @projectId; 

被從該查詢返回的信息看起來像波紋管:

'Management', 1 
'IT Department', 1 
'Production', 0 

什麼查詢是如此特別? projectId的條件包含在'join'部分中,而不是'where'部分。因此,'Production'組的行返回值爲0.當我們將projectId的條件移動到'where部分'時,記錄將不會出現在返回結果中。

最後這個問題 - 是否有可能使用一個lambda表達式實現類似的效果? (我知道我可以做到2個收藏和使用某種循環語句得到最終結果,但它不是這個問題的主題)

問候,

回答

0

LINQ外部聯接查詢需要的形式這個:

from x in collection 
join y in otherCollection on x.Key equals y.Key into g 
from o in g.DefaultIfEmpty() 
select new Whatever { 
    Something = x, 
    Other = o 
}; 

如果沒有相關y加入到x,然後從g選擇o將爲空

+0

Thanx for response。是的,我知道外連接的linq語法,但它不會'命中'projectId的參數(在這種情況下非常重要)。 – 2010-08-16 19:30:20

0

在黑暗中半拍攝:

from g in groups 
join u in users on 
new { a = g.id, b=u.projectid } equals new { a = u.groupid, b = [var_goes_here] } into t 
from u in ps.DefaultIfEmpty() 
select new { GroupName = g.name, HasUsers = u == null ? 0 : 1 }; 
3

好的,我認爲我自己弄明白了。生成的sql稍微複雜一些,然後在原始文章中提供,但結果集是相同的。

var query = db 
    .Groups 
    .GroupJoin(db.Users.Where(u => u.projectId == 1) , g => g.Id, u => u.groupId, (g, u) => new { u, g }) 
    .SelectMany(x => x.u.DefaultIfEmpty(), (g,u) => new {Group = g.g, Users = u}) 
    .Select(res => new {Group = res.Group.Name, Counter = (res.Users != null)});