EF Core在内存中而不是在SQL中执行GroupBy操作所需的解决方法

我正在使用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只是将查询编译到.GroupBy()到SQL,因此尝试将表的全部内容(此时写入大约1700万条记录)加载到内存中,其余的分组和排序是假设的在记忆中完成。

有任何建议如何重写这个查询,以便在SQL中完成繁重的工作?

EF Core 1.1.0不支持: https : //github.com/aspnet/EntityFramework/issues/2341

LINQ的GroupBy()运算符有时可以转换为SQL的GROUP BY子句,特别是在投影中应用聚合函数时。

遗憾的是,即使在EF Core 2.0.0中也不会支持它。

正如@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(); 

不是我希望的解决方案,但它有魅力。

正如您在本博客文章中看到的那样, GROUP BY将在2.1中得到支持,尚未发布,但预计 2017 年第一季度至 2017第四季度