如何获取计数列排序的组

时间:2010-11-01 14:58:58

标签: linq entity-framework linq-to-entities

用简单的英语很难问这个问题所以我会展示我想要做的事情。

这是我的SQL代码:

select top 100 [Name], COUNT([Name]) as total from ActivityLog  
where [Timestamp] between '2010-10-28' and '2010-10-29 17:00'  
group by [Name]  
order by total desc  

我需要在LinQ中写一下。到目前为止,我有以下内容:

var groups = from ActivityLog log in ctx.ActivityLog
 where log.Timestamp > dateFrom
 where log.Timestamp <= dateTo
 group log by log.Name;

但我没有COUNT(*)列来排序:(

2 个答案:

答案 0 :(得分:7)

我担心我对fluent语法(与查询语法相反)更为舒服,但这里有一个可能的LINQ答案:

 ctx.ActivityLog
   .Where(x => x.TimeStamp > dateFrom && x.TimeStamp <= dateTo)
  .GroupBy(x => x.Name)
  .Select(x => new { Name = x.Key, Total = x.Count() })
  .OrderByDescending(x => x.Total)
  .Take(100)

编辑:

好吧,我走出了我的舒适区,想出了一个查询语法版本,只是不要期望太多。我警告过你我的能力:

(from y in (
    from x in (
        from log in ActivityLog
        where log.Timestamp > dateFrom
        where log.Timestamp <= dateTo
        group log by log.Name)
    select new { Name = x.Key, Total = x.Count() })
orderby y.Total descending
select new { Name = y.Name, Total = y.Total }).Take(100)

答案 1 :(得分:3)

diceguyd30's answer技术上是LINQ并且是正确的。实际上,编译器将查询语法转换为那些可查询/可枚举方法。那说缺少的是使用group ... by ... into syntax。等效查询应该接近这个:

var query = from log in ctx.ActivityLog
            where log.TimeStamp > dateFrom && log.TimeStamp <= dateTo
            group log by log.Name into grouping
            orderby grouping.Count() descending
            select new { Name = grouping.Key, Total = grouping.Count() };

var result = query.Take(100);

请注意,在C#中,Take(100)方法在查询语法中没有等效项,因此您必须使用扩展方法。另一方面,VB.NET在查询语法中支持TakeSkip