【发布时间】:2019-05-07 10:40:22
【问题描述】:
我正在使用 Entity framework Core 2.1.4,并使用 C# 编写了一个基本示例查询,如下所示。
var myList = context.HastaAdres.OrderBy(p => p.ID).Take(20).GroupBy(p => p.IlKodu).Select(d => d.FirstOrDefault()).Select(p => p.ID).ToList();
但在 SQL 分析器中,运行代码如下所示。 SQL 中没有 group by,与经典的实体框架有很大不同。所以,结果也不同。结果,我只需要一列。但第一次查询,返回所有列。行数也与第二个查询不同。
Entity framework Core 生成的 SQL
SELECT [t].[ID], [t].[IlKodu], [t].[AcikAdres], [t].[BucakAdi], [t].[BucakKodu], [t].[BulvarKodu], [t].[CaddeKodu], [t].[CreatedBy], [t].[CreatedDate]
FROM (
SELECT TOP(20) [p].[ID], [p].[IlKodu], [p].[AcikAdres], [p].[BucakAdi], [p].[BucakKodu], [p].[BulvarKodu], [p].[CaddeKodu], [p].[CreatedBy], [p].[CreatedDate]
FROM [Ortak].[HastaAdres] AS [p]
ORDER BY [p].[ID]
) AS [t]
ORDER BY [t].[IlKodu]
当我在 Entity Framework 中尝试这种方法时,它正在生成完美的代码。
由实体框架生成的 SQL
SELECT
(SELECT TOP (1)
[Limit2].[ID] AS [ID]
FROM ( SELECT TOP (20) [Extent2].[ID] AS [ID], [Extent2].[IlKodu] AS [IlKodu]
FROM [Ortak].[HastaAdres] AS [Extent2]
ORDER BY [Extent2].[ID] ASC
) AS [Limit2]
WHERE ([Distinct1].[IlKodu] = [Limit2].[IlKodu]) OR (([Distinct1].[IlKodu] IS NULL) AND ([Limit2].[IlKodu] IS NULL))) AS [C1]
FROM ( SELECT DISTINCT [distinct].[IlKodu] AS [IlKodu]
FROM ( SELECT TOP (20)
[Extent1].[IlKodu] AS [IlKodu]
FROM [Ortak].[HastaAdres] AS [Extent1]
ORDER BY [Extent1].[ID] ASC
) AS [distinct]
) AS [Distinct1]
出现这种情况的原因是什么?
【问题讨论】:
-
您获得的数据是否正确? EF6 和 EFCore 是非常不同的产品,它们生成不同的 SQL 也就不足为奇了。
-
@DavidG 询问的是 materialized 结果(在
myList中),而不是 SQL 查询。 EF Core 使用混合方法,所以实际结果 != SQL 查询 -
我明白了。这是一个不同的故事,不幸的是,EF Core 仍然无法将许多构造转换为 SQL 并在本地评估它们。不过这很奇怪——即使客户评估需要 20 条记录也不应该花 10 分钟。如果您预先选择了您需要的字段,例如
context.HastaAdres.Select(p => new { p.ID, p.IlKodu }).OrderBy(…)...? -
@realist 为什么?我猜通常的因素 - 日程安排,缺乏时间/资源。它不是最终的——随着时间的推移而改进,可能有一天会被优化。问题是这就是现在的情况。不幸的是,我认为没有办法让他们生成所需的 SQL 查询。您是否尝试过我的建议 - 预先选择 2 个字段,然后按顺序进行排序 - 这应该会将 SQL 查询限制为 20 个包含 2 个字段的记录。
-
正如@IvanStoev 所说。 EF Core 仍然无法将 Linq
GroupBy转换为SQL GroubBy。如果您使用像Sum这样的聚合函数,他们只是添加了“一些”翻译。你可以在这里查看:docs.microsoft.com/en-us/ef/core/what-is-new/….
标签: c# .net entity-framework asp.net-core entity-framework-core