[英]EF Core “Group By could not be translated and will be evaluated locally.”
我正在使用Entity Framework Core 2.2.6对Sql Server数据库运行一个简单查询,但是GroupBy不在服务器上执行,而是在本地执行。
我有什么遗漏的东西会迫使该组进入服务器吗?
我试过的EF查询的2种变化:
public class Holiday
{
public int Id {get;set;}
public DateTime Date {get;set;}
public string Username {get;set;}
public string Approver {get;set;}
}
//version 1
await _dbContext.Holidays
.GroupBy(h => new { h.Date})
.ToDictionaryAsync(x => x.Key.Date, x => x.Select(x1 => x1.Username).ToList());
//version 2
await _dbContext.Holidays
.GroupBy(h => h.Date)
.ToDictionaryAsync(x => x.Key, x => x.Select(x1 => x1.Username).ToList());
两种变体均产生以下SQL:
SELECT [h].[Id], [h].[Approver], [h].[Date], [h].[HolidayTypeId], [h].[OwningRequestId], [h].[HolidayStatusId], [h].[Username]
FROM [Holidays] AS [h]
ORDER BY [h].[Date]
警告产生:
警告:Microsoft.EntityFrameworkCore.Query [20500] LINQ表达式'GroupBy([h] .Date,[h])'无法翻译,将在本地进行评估。
意见建议:
//group by string
await _dbContext.Holidays
.GroupBy(h => h.Username)
.ToDictionaryAsync(x => x.Key, x => x.Select(x1 => x1.Username).ToList());
//group by part of date
await _dbContext.Holidays
.GroupBy(h => h.Date.Year)
.ToDictionaryAsync(x => x.Key, x => x.Select(x1 => x1.Username).ToList());
--group by string
SELECT [h].[Id], [h].[Approver], [h].[Date], [h].[HolidayTypeId], [h].[OwningRequestId], [h].[HolidayStatusId], [h].[Username]
FROM [Holidays] AS [h]
ORDER BY [h].[Username]
--group by part of date
SELECT [h].[Id], [h].[Approver], [h].[Date], [h].[HolidayTypeId], [h].[OwningRequestId], [h].[HolidayStatusId], [h].[Username]
FROM [Holidays] AS [h]
ORDER BY DATEPART(year, [h].[Date])
这是因为没有这样的SQL查询。
像SQL一样思考。 如果要按日期组获取用户名,则两者都需要。
基本上:
await _dbContext.Holidays
.GroupBy(h => new { h.Date, h.Username})
.Select(g => new
{
g.Key.Date,
g.Key.Username
});
这将产生这样的SQL查询。
SELECT [h].[Date],[h].[Username]
FROM [Holidays] AS [h]
GROUP BY [h].[Date],[h].[Username]
之后,您可以根据需要使用数据创建字典的结构。
问题是,当您尝试对数据库进行分组时,实际上并没有实现组内值的方法。 您只能进入SELECT
分组列或非分组列的汇总值(通过SUM
等)。
例如:
SELECT [h].[Date], [h].[Username]
FROM [Holidays] AS [h]
该查询将产生结果集,其中每行将有两列,即日期和名称。
让我们尝试分组:
SELECT [h].[Date], [h].[Username]
FROM [Holidays] AS [h]
GROUP BY [h.Date]
完全不会评估此SQL查询,因为从SQL Server角度来看该查询无效。 错误消息将是
Column 'Holidays.Username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
总结一下,您可以按照@Ercan Tirman的建议进行操作,或者加载所有用户名和日期并在内存中将它们分组:
var dateAndUsername = await _dbContext.Holidays
.Select(x => new {x.Date, x.Username})
.ToArrayAsync();
Dictionary<DateTime, List<string>> grouped = dateAndUsername
.GroupBy(x => x.Date)
.ToDictionary(x => x.Key, x => x.Select(y => y.Username).ToList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.