【发布时间】:2020-05-18 23:56:12
【问题描述】:
我不时听到,EF Core 3.1 现在能够优化分组和几个聚合函数,如 sum 在数据库上执行。为什么我的 C# 代码会将此严重未优化的 SQL 代码发送到数据库服务器?
using var dbContext = new DatabaseContext();
var someTableData = await dbContext.SomeTable
.GroupBy(x => x.Foobar)
.Select(x => new { Foobar = x.Key, Quantity = x.Sum(y => y.Quantity) })
.OrderByDescending(x => x.Quantity)
.Take(10)
.ToListAsync();
SQL(从实体框架日志复制):
SELECT [...] FROM public."SomeTable"
如您所见:查询不包含任何排序、分组、汇总……
我通过创建视图解决了我的问题,因为原始 ef 核心查询将应用程序的 RAM 使用量增加了 2GB(在 2 秒内),因为有很多表条目。但我的问题仍然存在:我做错了什么?是不是因为我使用的是 PostgreSQL (Npgsql.EntityFrameworkCore.PostgreSQL v3.1.0)?
【问题讨论】:
-
SomeTable 可能是一个视图吗?
-
很可能是因为你使用的是Npgsql,因为它不是微软官方维护的,而是第三方Data Provider。而且由于数据提供者负责将 LINQ 表达式实际转换为任何内容(对您来说是 PSQL),因此 Npsql 数据提供者可能不支持这些功能(目前)。您听到的内容可能仅适用于 MS 开发的数据提供者
-
您可以使用准备好的语句 (which are supported by Npgsql) 手动编写 SQL 查询然后执行它,这样您可以确保您的 SQL 查询按照您的意愿进行优化
-
嗯,这表示客户端评估,因此似乎不是 EF Core 3.0+ 的输出。客户端评估已停用,如果 EF Core 无法翻译您的
GroupBy查询或其中的某些部分,您应该获得运行时异常。x.Foobarbtw 的类型是什么? -
@jarlh SomeTable 绝对是一张桌子。
标签: c# sql postgresql entity-framework-core ef-core-3.1