简体   繁体   English

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

[英]EF Core “Group By could not be translated and will be evaluated locally.”

I am running a simple query against an Sql Server database using Entity Framework Core 2.2.6 however the GroupBy is not being executed on the server, instead it is being executed locally. 我正在使用Entity Framework Core 2.2.6对Sql Server数据库运行一个简单查询,但是GroupBy不在服务器上执行,而是在本地执行。

Is there something i'm missing that will force the group by onto the server? 我有什么遗漏的东西会迫使该组进入服务器吗?

The 2 variations of EF query i have tried: 我试过的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());

Both variations produces the following SQL: 两种变体均产生以下SQL:

SELECT [h].[Id], [h].[Approver], [h].[Date], [h].[HolidayTypeId], [h].[OwningRequestId], [h].[HolidayStatusId], [h].[Username]
FROM [Holidays] AS [h]
ORDER BY [h].[Date]

warning produced: 警告产生:

warnwarn: Microsoft.EntityFrameworkCore.Query[20500] The LINQ expression 'GroupBy([h].Date, [h])' could not be translated and will be evaluated locally. 警告:Microsoft.EntityFrameworkCore.Query [20500] LINQ表达式'GroupBy([h] .Date,[h])'无法翻译,将在本地进行评估。

Suggestions from comments: 意见建议:

//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])

It's because there is no SQL query like that. 这是因为没有这样的SQL查询。

Think like SQL. 像SQL一样思考。 If you want to get Usernames by group of Dates, you need both of those. 如果要按日期组获取用户名,则两者都需要。

Basically : 基本上:

await _dbContext.Holidays
    .GroupBy(h => new { h.Date, h.Username})
    .Select(g => new
        {
          g.Key.Date,
          g.Key.Username
        });

This will produce a SQL query like this. 这将产生这样的SQL查询。

SELECT [h].[Date],[h].[Username]
FROM [Holidays] AS [h]
GROUP BY [h].[Date],[h].[Username]

After that you can use the data to create the structure of your dictionary however you want. 之后,您可以根据需要使用数据创建字典的结构。

The problem is that when you're trying to group in the database, you don't really have the means to materialize values inside a group. 问题是,当您尝试对数据库进行分组时,实际上并没有实现组内值的方法。 You only get to SELECT grouped columns or aggregated values (via SUM , etc.) of non-grouped columns. 您只能进入SELECT分组列或非分组列的汇总值(通过SUM等)。

For example: 例如:

SELECT [h].[Date], [h].[Username]
FROM [Holidays] AS [h]

This query would produce result set of which every row would have two columns, date and name. 该查询将产生结果集,其中每行将有两列,即日期和名称。

Let's try grouping though: 让我们尝试分组:

SELECT [h].[Date], [h].[Username]
FROM [Holidays] AS [h]
GROUP BY [h.Date]

This SQL query wouldn't be evaluated at all because it's invalid from SQL server perspective. 完全不会评估此SQL查询,因为从SQL Server角度来看该查询无效。 Error message would be 错误消息将是

Column 'Holidays.Username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Summing all this up, you can either do what @Ercan Tirman has suggested, or, load all the usernames and dates and group them in-memory: 总结一下,您可以按照@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.

相关问题 EF核心,Any无法翻译,将在本地进行评估 - EF core, Any could not be translated and will be evaluated locally EF Core ValueObject 比较无法翻译,将在本地评估 - EF Core ValueObject comparison could not be translated and will be evaluated locally 实体框架核心 2.1:无法翻译,将在本地进行评估 - Entity framework core 2.1: could not be translated and will be evaluated locally LINQ 表达式 'FirstOrDefault()' 无法翻译,将在本地求值 - The LINQ expression 'FirstOrDefault()' could not be translated and will be evaluated locally 无法翻译 LINQ 表达式,将在本地计算 - The LINQ expression could not be translated and will be evaluated locally LINQ 表达式无法翻译,将在本地计算 - LINQ expression could not be translated and will be evaluated locally EF Core 3.1 - 无法翻译 LINQ 表达式(左连接与 group by) - EF Core 3.1 - The LINQ expression could not be translated (left joins with group by) 无法翻译 EF 核心查询 - EF core query could not be translated EF Core 3 Linq 无法翻译 - EF Core 3 Linq could not be translated LINQ 表达式中的 OData $top 查询无法转换,将使用 EF Core 和 .NET Core 2.2 在本地进行评估 - OData $top query in LINQ expression could not be transalted and will be evaluated locally using EF Core and .NET Core 2.2
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM