具有聚合函数的Linq查询

时间:2010-05-29 12:49:50

标签: linq linq-to-entities

我试图找出如何编写linq查询以执行下面的SQL查询之类的聚合:

select d.ID, d.FIRST_NAME, d.LAST_NAME, count(s.id) as design_count
from tbldesigner d inner join
TBLDESIGN s on d.ID = s.DESIGNER_ID
where s.COMPLETED = 1 and d.ACTIVE = 1
group by d.ID, d.FIRST_NAME, d.LAST_NAME
Having COUNT(s.id) > 0

如果使用linq查询甚至可以这样做,有人可以请给我一个例子。 提前致谢, 比利

3 个答案:

答案 0 :(得分:2)

原始SQL查询的更直接的翻译如下所示:

var q = 
    // Join tables TblDesign with TblDesigner and filter them
    from d in db.TblDesigner 
    join s in db.TblDesign on d.ID equals s.DesignerID
    where s.Completed && d.Active
    // Key and values used for grouping (note, you don't really need the
    // value here, because you only need Count of the values in a group, but
    // in case you needed anything from 's' or 'd' in 'select', you'd write this
    let value = new { s, d } 
    let key = new { d.ID, d.FirstName, d.LastName }
    group value by key into g 
    // Now, filter the created groups (return only non-empty) and select 
    // information for every group
    where g.Count() > 0
    select { ID = g.Key.ID, FirstName = g.Key.FirstName, 
             LastName = g.Key.LastName, Count = g.Count() };

HAVING子句转换为普通where,在使用group ... by对值进行分组后应用。分组的结果是一组(另一个集合),因此您可以使用where来过滤组。在select子句中,您可以从密钥(用于分组)和值汇总(使用g.Count())返回信息

编辑:正如mmcteam指出的那样(请参阅注释),where g.Count() > 0子句不是必需的,因为join已经保证了这一点。我会把它留在那里,因为它显示了如何翻译HAVING一般的句子,所以在其他情况下它可能会有所帮助。

答案 1 :(得分:0)

我是这样做的。请注意,我习惯使用linqtosql并且不知道linqtoentities中的查询是否存在差异。

var query =
  from d in myObjectContext.tbldesigner
  where d.ACTIVE == 1
  let manys =
    from s in d.tbldesign
    where s.COMPLETED == 1
    select s
  where manys.Count() > 0
  select new
  {
    d.ID, d.FIRST_NAME, d.LAST_NAME,
    DesignCount = manys.Count()
  };

答案 2 :(得分:0)

忽略令我困惑的s.id(请参阅我对该问题的评论),这是一个简单的查询,它会生成一个having子句。当然,在这种情况下,它是一个毫无价值的例子,因为在这种情况下,计数总是大于0。

无论如何,如果您使用SQL to Entities,则应使用实体映射来访问外键关系,而不是手动执行连接或子查询。

var results = from d in db.tbldesigner 
              where d.TBLDESIGN.COMPLETED && d.ACTIVE 
              group d by new {d.ID, d.FIRST_NAME, d.LAST_NAME} into g
              where g.Count() >= 0
              select new {
                 d.ID, d.FIRST_NAME, d.LAST_NAME,
                 Count = g.Count()
              };

注意:这是未经测试的(并且未编译)因此可能存在一些问题,但这是我要开始的地方。