并非所有 Linq 方法都可以转换为 SQL 查询(这就是您的表达式无法编译的原因)。
因此,使用 Take() 方法结合 order by 子句可以获得相同的结果。
按照你的例子:
var mostExpensiveProductByCategory = dbContext.Products
.GroupBy(x => x.CategoryId).Select(x => new
{
CategoryId = x.Key,
Product = x.OrderByDescending(p => p.Price).Take(1)
})
.ToList();
var cheapestProductByCategory = dbContext.Products
.GroupBy(x => x.CategoryId).Select(x => new
{
CategoryId = x.Key,
Product = x.OrderBy(p => p.Price).Take(1)
})
.ToList();
UPDATE:
为了满足您的要求并避免内存中分组,我建议您使用导航属性,如下所示:
var mostExpensiveProductByCategory = dbContext.Categories.Select(x => new
{
x.CategoryId,
Products = x.Products.OrderByDescending(p => p.Price).Take(1)
}).ToList();
这将产生以下查询输出:
SELECT [c].[CategoryId], [t0].[ProductId], [t0].[CategoryId], [t0].[Price]
FROM [Categories] AS [c]
LEFT JOIN ( SELECT [t].[ProductId], [t].[CategoryId], [t].[Price]
FROM ( SELECT [p].[ProductId], [p].[CategoryId], [p].[Price], ROW_NUMBER() OVER(PARTITION BY [p].[CategoryId] ORDER BY [p].[Price] DESC) AS [row]
FROM [Products] AS [p] ) AS [t] WHERE [t].[row] <= 1 ) AS [t0] ON [c].[CategoryId] = [t0].[CategoryId]
ORDER BY [c].[CategoryId], [t0].[CategoryId], [t0].[Price] DESC, [t0].[ProductId]