【问题标题】:lambda expression - equivalent of sql outer joinlambda 表达式 - 相当于 sql 外连接
【发布时间】:2011-03-30 14:29:45
【问题描述】:

我需要用 C# 编写从 DB 中返回一些特定字典的方法。假设存储在 2 个表中的数据如下所示:

表组(id、名称):

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 个集合并使用某种循环语句得到最终结果,但这不是这个问题的主题)

问候,
烤肉

【问题讨论】:

    标签: c# lambda


    【解决方案1】:

    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将为空

    【讨论】:

    • 感谢您的回复。是的,我知道外部连接的 linq 语法,但它没有“命中” projectId 的参数(在这种情况下非常重要)。
    【解决方案2】:

    在黑暗中半拍:

    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)});
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-09
        • 1970-01-01
        • 2012-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多