繁体   English   中英

EF核心“分组依据无法翻译,将在本地进行评估。”

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM