lambda表达式 - 相当于sql外连接

时间:2010-08-16 18:50:38

标签: c# lambda

我需要在C#中编写方法,它将从DB返回一些特定的字典。可以说,存储在2个表中的数据如下所示:

表组(id,name):

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

用户(id,name,groupId,projectId):

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 part'时,记录将不会出现在返回结果中。

最后一个问题 - 使用一个lambda表达式可以实现类似的效果吗? (我知道我可以实现2个集合并使用某种循环语句获得最终结果,但它不是这个问题的主题)

的问候,

3 个答案:

答案 0 :(得分: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)});

答案 1 :(得分:0)

LINQ Outer Join查询采用以下形式:

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,则从o中选择的g将为空

答案 2 :(得分: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 };