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

Sha*_*ica 4 c# entity-framework-core

我正在使用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();
Run Code Online (Sandbox Code Playgroud)

在测试代​​码中,这可以很好地工作并返回预期的数据。但是,当部署到具有真实数据的真实环境时,它会超时。为什么?好吧,我在SQL服务器上放了一个嗅探器,这是实际的SQL:

SELECT [t].[Field1], [t].[Field2], [t].[Field3], [t].[Field4], [t].[Field5]
FROM [dbo].[MyTable] AS [t]
ORDER BY [t].[Field1]
Run Code Online (Sandbox Code Playgroud)

哦。好吧,这可以解释它。EF只是将查询编译.GroupBy()到SQL中,因此尝试将表的全部内容(在撰写本文时,此记录约为1700万条记录)加载到内存中,其余的分组和排序应该在记忆。

有什么建议可以重新处理此查询,以便在SQL中完成繁重的工作?

Sha*_*ica 5

正如@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();
Run Code Online (Sandbox Code Playgroud)

不是我希望的解决方案,但是它很吸引人。