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