Auch Entity Framework Core 1.1 führt Gruppierungen immer noch im RAM aus

Der Dotnet-Doktor  –  0 Kommentare

Eines der größten Probleme mit Microsoft komplett überarbeiteten OR-Mapper Entity Framework Core war bisher, dass Gruppierungen mit group by nicht in der Datenbank ausgeführt werden, sondern im RAM.

Microsoft hat zwar für das letzte Woche veröffentlichte Entity Framework Core 1.1 angekündigt: "Improved LINQ translation: In the 1.1 release we have made good progress improving the EF Core LINQ provider. This enables more queries to successfully execute, with more logic being evaluated in the database (rather than in memory)." Allerdings musste ich feststellen, dass diese Verbesserung nicht für Gruppierungen gilt.

Aus dem LINQ-Befehl, der liefern soll, wie viele Flüge es von jedem Abflugort gibt

var gruppen = from p in ctx.FlugSet               
orderby p.FreiePlaetze
group p by p.Abflugort into g
select new { Ort = g.Key, Anzahl = g.Count() };

macht Entity Framework Core auch in der Version 1.1 einen SQL-Befehl, der alle Datensätze aus der Datenbank liest und im RAM gruppiert. Bei vielen Datensätzen führt dies zu einer unerträglich schlechten Performanz. Schade!

SELECT [p].[FlugNr], [p].[Abflugort], [p].[Bestreikt], [p].[CopilotId],
[p].[FlugDatum], [p].[Fluggesellschaft], [p].[FlugzeugTypID],
[p].[FreiePlaetze], [p].[LetzteAenderung], [p].[Memo],
[p].[NichtRaucherFlug], [p].[PilotId], [p].[Plaetze], [p].[Preis],
[p].[Timestamp], [p].[Zielort]

FROM [Flug] AS [p]

ORDER BY [p].[Abflugort]

Sogar dann, wenn man mit gruppen.Count() nur die Anzahl der Gruppen wissen will, holt Entity Framework Core 1.0 und 1.1 alle Datensätze aus der Datenbank und zählt diese im RAM.

Entity Framework Core erlaubt zwar auch weiterhin, direkt SQL-Befehle zur Datenbank zu senden, allerdings können diese derzeit nur auf Entitätsklassen abgebildet werden und nicht auf eine Klasse, die der Struktur des Gruppierungsergebnisses entspricht. In diesem Fall können sich Entwickler dann vorerst nur damit behelfen, dass es in einem Prozess möglich ist, das neue Entity Framework Core und das alte Entity Framework parallel zu betreiben, um dann solche Befehle über das alte Entity Framework abzusenden. Immerhin führt jede Ausführung von Datenoperationen im RAM zu einer Warnung im Laufzeitprotokoll des ORM; per Konfigurationseinstellung können Entwickler diese Warnung auch zum Laufzeitfehler hochstufen, um deutlicher zu merken, wenn sie eine RAM-Operation initiieren.

Diese Schwäche bezeichnet das Entwicklungsteam in seiner Roadmap als "kritisch", dennoch bleibt das Problem auch in Version 1.1 bestehen.

Details zu Entity Framework Core erfahren Sie am 29. November, um 19 Uhr bei meinem kostenfreien Vortrag bei der .NET User Group in Essen.