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

发布于 2024-09-14 18:01:11 字数 901 浏览 3 评论 0原文

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

表 组(id,名称):

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

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

问候,

I need to write the method in C# that will return some specific dictionary from DB. Lets say that data stored in 2 tables looks like:

table Groups (id, name):

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

The Users (id, name, groupId, projectId):

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

Now I need to check that in every project every group have no less than one user. The sql query to achieve this information will be:

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;  

The information that are returned from this query looks like bellow:

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

What's so special in the query? The condition for projectId is included in 'join' part, not 'where' part. In consequence the row for 'Production' group is returned with value 0. When we move condition for projectId to 'where part' the record will not be present in the return result.

Finally the question - is it possible to achieve similar effect using one lambda expression? (I know that I can achieve 2 collections and using some kind of loop statement get the final result, but it's not a subject of this question)

regards,
yaki

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小镇女孩 2024-09-21 18:01:11

好吧,我想是我自己想出来的。生成的 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)});

Ok, I think that I figured it out by myself. The sql produced is a little bit more complicated then provided in original post, but the resultset is the same.

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)});
情独悲 2024-09-21 18:01:11

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

LINQ Outer Join queries take the form of this:

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

If there is no related y to join to the x, then the o selected from g will be null

一身骄傲 2024-09-21 18:01:11

半暗环境下拍摄:

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

Semi shot in the dark:

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 };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文