簡體   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