2010-08-16 26 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)});