LINQ – 左连接,分组和计数

假设我有这个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() } 

谢谢!

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

考虑使用子查询:

 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, Count = cCount } ; 

如果查询types通过关联连接,则简化为:

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

晚答案:

如果你所做的只是Count(),你根本不需要左连接 。 请注意, join...into实际上被转换为GroupJoin ,它返回如new{parent,IEnumerable<child>}这样的分组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 (而没有intoJoinJoin ):

 context.ParentTable .GroupJoin( inner: context.ChildTable outerKeySelector: parent => parent.ParentId, innerKeySelector: child => child.ParentId, resultSelector: (parent, children) => new { parent.Id, Count = children.Count() } ); 
  (from p in context.ParentTable join c in context.ChildTable on p.ParentId equals c.ChildParentId into j1 from j2 in j1.DefaultIfEmpty() select new { ParentId = p.ParentId, ChildId = j2==null? 0 : 1 }) .GroupBy(o=>o.ParentId) .Select(o=>new { ParentId = o.key, Count = o.Sum(p=>p.ChildId) }) 

虽然LINQ语法背后的想法是模仿SQL语法,但不应该总是想到直接将您的SQL代码转换为LINQ。 在这个特定的情况下,我们不需要进入组,因为join是一个组连接。

这是我的解决scheme:

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

与这里大多数投票的解决scheme不同,我们不需要j1j2Count中的空检查(t => t.ChildId!= null)