GroupBy funktioniert in Entity Framework Core 2.1 Preview 1 immer noch nicht so ganz

Der Dotnet-Doktor  –  1 Kommentare

Aggregatoperatoren wie Min(), Max(), Sum() und Average() funktionieren, nicht aber Count().

Ich hatte wiederholt berichtet, dass Entity Framework Core die bedeutende Schwäche, den LINQ-Operator GroupBy() nicht in entsprechendes GROUP BY in SQL umzusetzen, sondern alle Datensätze ins RAM zu laden und dort zu gruppieren (vgl. mein Beitrag zu Entity Framework Core 1.0/1.1 und Entity Framework Core 2.0).

Für die erste Vorschauversion von Entity Framework Core 2.1, die vor drei Wochen erschienen ist, hat Microsoft dokumentiert: "We now support translating it to the SQL GROUP BY clause in most common cases."

Gerade habe ich meine eigenen Testfälle durchlaufen lassen und wurde schon beim ersten Fall enttäuscht. Aus

// Simple Group by (Number of flights per destination)
var groups  = (from p in ctx.FlightSet
group p by p.Departure into g
select new { City = g.Key,
Count = g.Count() })
.Where(x => x.Count > 5).OrderBy(x => x.Count).ToList();

produziert Entity Framework Core dieses SQL, das ungültig ist:

SELECT [p].[Departure], COUNT(*)
FROM [Flight] AS [p]
WHERE COUNT(*) > 5
GROUP BY [p].[Departure]

denn: "An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference."

Der Fehler scheint an dem Count-Operator zu hängen. Andere Aggregatoperatoren wie Min(), Max(), Sum() und Average() funktionieren. Diese LINQ-Abfrage:

// Simple Group by: Min, Max, Sum und Average of FreeSeats per Destination
var groups = (from p in ctx.FlightSet
group p by p.Departure into g
select new { City = g.Key, Min = g.Min(x => x.FreeSeats),
Max = g.Max(x => x.FreeSeats),
Sum = g.Sum(x => x.FreeSeats),
Avg = g.Average(x => x.FreeSeats) });

führt in Entity Framework Core 2.1 Preview 1 zu diesem korrekten SQL:

SELECT [p].[Departure], MIN([p].[FreeSeats]), MAX([p].[FreeSeats]), 
SUM([p].[FreeSeats]), AVG(CAST([p].[FreeSeats] AS float))
FROM [Flight] AS [p]
GROUP BY [p].[Departure]

Ich habe eine Bug-Meldung auf Github eingetragen.

Mein nächster Vortrag zu Entity Framework Core ist am 11.4.2018 auf dem Magdeburger Developer Days. Ich hoffe, ich kann dort berichten, dass Count() dann auch ein "common case" ist.