我正在使用Entity Framework Core 1.1.0(此时升级不是一个选项,因为在以后的版本中会发生重大变化)。我的查询格式如下:
var q = db.MyTable
.GroupBy(t => new { t.Field1 })
.Select(g => new
{
g.Key.Field1,
MaxField2 = g.Max(x => x.Field2)
})
.ToList();
在测试代码中,这很有效,并返回预期的数据。但是当使用真实数据部署到真实环境时,它会超时。为什么?好吧,我在SQL服务器上放了一个嗅探器,这是实际的SQL:
SELECT [t].[Field1], [t].[Field2], [t].[Field3], [t].[Field4], [t].[Field5]
FROM [dbo].[MyTable] AS [t]
ORDER BY [t].[Field1]
喔。好吧,这可以解释它。 EF仅将查询编译到SQL .GroupBy()
,从而尝试将表中的整个内容(此时写入大约1700万条记录)加载到内存中,并且其余的分组和排序应该在内存中完成。
有关如何重写此查询的任何建议,以便在SQL中完成繁重的工作吗?
答案 0 :(得分:3)
EF Core 1.1.0不支持:https://github.com/aspnet/EntityFramework/issues/2341
LINQ的GroupBy()运算符有时可以转换为SQL的GROUP BY子句,特别是在投影中应用聚合函数时。
遗憾的是,即使在EF Core 2.0.0中也不会支持它。
答案 1 :(得分:3)
正如@xanatos指出的那样,EF Core 1.1.0(甚至不是2.0.0)都不支持。但是,有一种解决方法,使用文字SQL:
var q = db.MyTable
.FromSql("select t.* from " +
" (select distinct Field1 from MyTable) t0 " +
"cross apply " +
" (select top 1 t.* from MyTable t " +
" where t.Field1 = t0.Field1 " +
" order by t.Field2 desc) t")
.Select(t => new
{
t.Field1,
MaxField2 = t.Field2
})
.ToList();
不是我希望的解决方案,但它有魅力。
答案 2 :(得分:2)
正如您在blog entry中看到的那样,{1}}将在2.1中得到支持,但尚未发布,但expected for Q1-Q2 2018 2017年第4季度