代码之家  ›  专栏  ›  技术社区  ›  pbz

Linq-左联接、分组依据和计数

  •  161
  • pbz  · 技术社区  · 15 年前

    假设我有这个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到SQL?我陷入了计数(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() }
    

    谢谢您!

    5 回复  |  直到 7 年前
        1
  •  182
  •   Mehrdad Afshari    15 年前
    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) }
    
        2
  •  55
  •   Brian Webster    12 年前

    考虑使用子查询:

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

    如果查询类型是通过关联连接的,这将简化为:

    from p in context.ParentTable 
    let cCount = p.Children.Count()
    select new { ParentId = p.Key, Count = cCount } ;
    
        3
  •  31
  •   Dai    7 年前

    迟到的回答:

    不需要左边的加入 如果你所做的一切都是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() }
    

    在扩展方法语法A中 join into 等于 组联接 (而A) 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() }
        );
    
        4
  •  7
  •   雪域飞貂    15 年前
     (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) })
    
        5
  •  7
  •   Mosh    9 年前

    尽管Linq语法背后的想法是模拟SQL语法,但您不应该总是考虑直接将SQL代码转换为Linq。在这种情况下,我们不需要这样做 组入 自从 加入 是一个组联接本身。

    我的解决方案是:

    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 , J2 和空签入 计数(t=>t.childID!=空)