如何在行集上生成许多聚合

时间:2010-10-01 12:36:35

标签: linq linq-to-entities

我正在艰难地映射一个简单的T-SQL查询,例如这个

select min(price) as MinPrice, max(price) as MaxPrice, avg(price) as AvgPrice
from titles

到Linq表达式,例如:

var answer = from t in Titles
select new { MinPrice=Min(t.Price), MaxPrice=Max(t.Price), AvgPrice=Avg(t.Price)};

显然这不起作用,因为Min在这种情况下不存在。我也理解需要某种Group子句,但由于我在原始的T-Sql语句中没有group by,所以我不确定该linq查询中的group by如何应用。

我正在使用EF 4,但在这种情况下,我怀疑在这个例子中应该重要。

2 个答案:

答案 0 :(得分:2)

不确定它适用于EF,但你可以尝试这样的事情:

var query =
    from p in products
    group p by 0 into g
    select new
    {
        Min = g.Min(p => p.Price),
        Max = g.Max(p => p.Price),
        Avg = g.Average(p => p.Price)
    };
var result = query.First();

编辑:刚刚在LINQPad中尝试使用Linq to SQL,它可以工作......所以它可能也适用于EF


上面的查询生成以下SQL:

SELECT TOP (1) [t2].[value] AS [Min], [t2].[value2] AS [Max], [t2].[value3] AS [Avg]
FROM (
    SELECT MIN([t1].[Price]) AS [value], MAX([t1].[Price]) AS [value2], AVG([t1].[Price]) AS [value3]
    FROM (
        SELECT @p0 AS [value], [t0].[Price]
        FROM [Product] AS [t0]
        ) AS [t1]
    GROUP BY [t1].[value]
    ) AS [t2]

SELECT TOP(1)部分仅在那里因为调用了First

这显然不是最优的,但我认为SQL Server足够聪明,可以将其优化为更简单的...

答案 1 :(得分:0)

var prices = titles.Select(t => t.Price);
var answer = new { min = prices.Min(), max = prices.Max(), avg = prices.Average(); }