将GroupBy和Avg的SQL查询转换为LINQ

时间:2017-03-15 16:37:03

标签: c# linq

我在SQL中有一个简单的查询:

SELECT 
    l.State,
    AVG(ls.Amount) As StateAvg
FROM 
    LeadSales ls 
    JOIN  LEADS l on ls.LeadID = l.LeadID
GROUP BY 
    l.State

这有效:

enter image description here

将此转换为LINQ时遇到一些麻烦(其中queryLeadSales表的IQueryable ...)

var StateList = from q in query
                 group q by new
                 {
                      q.Lead.State,
                      q.Amount // <--- it this corrcect?
                 } into g
                 select new AverageLeadSalesPriceItem
                 {
                      StateCode = g.Key.State,
                      StateAverage = ????
                  };

使用:

public class AverageLeadSalesPriceItem
{
    public string StateCode { get; set; }
    public decimal? StateAverage { get; set; }
}

2 个答案:

答案 0 :(得分:1)

这就像

一样
var StateList = from q in query
                 group q by new
                 {
                      q.Lead.State
                 } into g
                 select new AverageLeadSalesPriceItem
                 {
                      StateCode = g.Key.State,
                      StateAverage = g.Average( a=>a.Amount )
                  };

请注意,如果要动态计算聚合(如在SQL中),可以使用像NReco PivotData这样的专用库(我是这个库的开发人员,对于单部署项目是免费的。)

答案 1 :(得分:1)

你离我不远。 group子句应该按照您在SQL中分组的相同字段进行分组,然后分组构造对象g就像它自己的Enumerable / Queryable一样,包含该组的所有行,您可以调用聚合函数上。因此,只有一个字段定义组密钥,不需要匿名类型,然后您只需在g上调用Average(),定义标识该字段的投影平均值。

var StateList = from q in query
             group q by q.Lead.State into g
             select new AverageLeadSalesPriceItem
             {
                  StateCode = g.Key,
                  StateAverage = g.Average(gq=>gq.Amount),
             };

请记住,如果基于可查询的提供程序(如EF DbSet),您的Linq查询不会对数据库执行,除非您通过调用返回一个方法的方法隐式地指示您需要“真正的”内存中对象或更多表示对象(First(),ToArray()等)或显式使用AsEnumerable()扩展方法。