LINQ - 左连接、分组依据和计数

问题描述 投票:0回答:5

假设我有这个 SQL:

SELECT p.ParentId, COUNT(c.ChildId)
FROM ParentTable p
  LEFT OUTER JOIN ChildTable c ON p.ParentId = c.ChildParentId
GROUP BY p.ParentId

如何将其转换为 LINQ to SQL?我陷入了 COUNT(c.ChildId) 的困境,生成的 SQL 似乎总是输出 COUNT(*)。这是我到目前为止得到的:

from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into j1
from j2 in j1.DefaultIfEmpty()
group j2 by p.ParentId into grouped
select new { ParentId = grouped.Key, Count = grouped.Count() }

谢谢!

c# .net linq linq-to-sql
5个回答
199
投票
from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into j1
from j2 in j1.DefaultIfEmpty()
group j2 by p.ParentId into grouped
select new { ParentId = grouped.Key, Count = grouped.Count(t=>t.ChildId != null) }

64
投票

考虑使用子查询:

from p in context.ParentTable 
let cCount =
(
  from c in context.ChildTable
  where p.ParentId == c.ChildParentId
  select c
).Count()
select new { ParentId = p.Key, /* p.foo, p.bar, p.Baz, */ Count = cCount } ;

如果查询类型通过关联连接,则可以简化为:

from p in context.ParentTable 
let cCount = p.Children.Count()
select new { ParentId = p.Key, Count = cCount } ;

39
投票

迟到的答案:

如果您所做的只是 Count(),那么您根本不需要左连接。请注意,join...into实际上被翻译为

GroupJoin
,它返回像
new{parent,IEnumerable<child>}
这样的分组,所以你只需要在组上调用
Count()

from p in context.ParentTable join c in context.ChildTable on p.ParentId equals c.ChildParentId into g select new { ParentId = p.Id, Count = g.Count() }

在扩展方法语法中,
join into

相当于

GroupJoin
(而没有
join
into
Join
):

context.ParentTable .GroupJoin( inner: context.ChildTable outerKeySelector: parent => parent.ParentId, innerKeySelector: child => child.ParentId, resultSelector: (parent, children) => new { parent.Id, Count = children.Count() } );



8
投票


8
投票
group into

因为 join into 本身就是一个组连接。 这是我的解决方案:

from p in context.ParentTable join c in context.ChildTable on p.ParentId equals c.ChildParentId into joined select new { ParentId = p.ParentId, Count = joined.Count() }

与这里投票最多的解决方案不同,我们不需要 
j1

j2Count(t => t.ChildId != null) 中的 null 检查

© www.soinside.com 2019 - 2024. All rights reserved.