Entity Framework Core im KMU: Was Nick Chapsas dir nicht sagt

Nick Chapsas erklärt EF Core technisch sauber. Was er nicht erklärt: warum du im Mittelstand trotzdem oft falsch liegst, wenn du EF Core einfach nimmst weil es Standard ist.

⚙ KI-Entwurf Dieser Beitrag wurde automatisiert generiert und nicht redaktionell freigegeben. Behandelt ihn entsprechend.

Letztes Jahr war ich bei einem Maschinenbauer in Baden-Württemberg. 180 Mitarbeitende, solide Auftragslage, IT-Abteilung mit zwei Entwicklern und einem externen Dienstleister. Die hatten eine intern gewachsene .NET-Anwendung für Auftragssteuerung — und die war langsam. Nicht dramatisch langsam, aber spürbar langsam. Jedes Mal wenn ein Sachbearbeiter die Auftragsübersicht öffnete, wartete er drei bis fünf Sekunden.

Ich schaue mir den Code an. EF Core, DbContext per Request, LINQ-Queries die eigentlich harmlos aussehen. Und dann sehe ich es: Change Tracking aktiv auf einer Read-Only-Seite, die 400 Datensätze lädt. Kein AsNoTracking, keine Projektion. EF Core trackt brav alle 400 Objekte im Speicher, obwohl die Seite nie schreibt. Das ist kein Fehler von EF Core. Das ist ein Fehler davon, EF Core zu benutzen ohne zu verstehen was es im Hintergrund tut.


Nick Chapsas hat einen soliden Einsteiger-Artikel zu Entity Framework Core geschrieben. Er erklärt die Geschichte von EF über EF Core, zeigt CRUD-Operationen mit dem Change Tracker, und gibt einen ehrlichen Überblick über die Versionsevolution von 2.x bis 9. Besonders gut: er versteckt die Performance-Kritik nicht, sondern nennt Change Tracking, LINQ-Translation und Abstraktions-Overhead direkt als historische Schwachstellen. Das ist fair. Der Artikel richtet sich an .NET-Entwickler, die EF Core noch nicht kennen, und erfüllt diesen Zweck technisch kompetent.

Was der Artikel zwangsläufig nicht leistet: er sagt dir nicht, wann du EF Core nehmen solltest und wann nicht. Das ist auch nicht sein Job — es ist ein Getting-Started-Post. Mein Job als Berater ist es, genau diese Frage zu beantworten. Und die Antwort ist differenzierter als "nimm EF Core, weil es Standard ist."


Wie das im Mittelstand wirklich landet

Im KMU mit 30 bis 300 Mitarbeitenden triffst du typischerweise auf drei Konstellationen:

Konstellation 1: Neue Eigenentwicklung, ein bis drei .NET-Entwickler Hier ist EF Core fast immer die richtige Wahl. Die Entwickler kennen es, die Migrations sind sauber versionierbar, Code-First passt gut zu agilem Vorgehen wo die Datenbankstruktur noch nicht feststeht. Der Overhead durch Change Tracking ist bei typischen KMU-Lastprofilen — sagen wir 50 gleichzeitige Nutzer, CRUD-lastige Backoffice-Anwendungen — völlig irrelevant. Du gewinnst Entwicklungsgeschwindigkeit und verlierst nichts was dir fehlt.

Konstellation 2: Gewachsene Altanwendung mit bestehender Datenbankstruktur Hier wird es komplizierter. EF Core im Database-First-Modus funktioniert, aber du kämpfst schnell gegen die Abstraktion statt mit ihr. Wenn die Datenbank zwanzig Jahre gewachsen ist, mit Stored Procedures, Views, und einem Schema das kein Entwickler mehr vollständig kennt — dann ist Dapper ehrlicher. Du schreibst SQL das du lesen und debuggen kannst, nicht LINQ das du erst mental in SQL zurückübersetzen musst um zu verstehen warum der Query Optimizer verrückt spielt.

Ich habe in Mandaten mehrfach gesehen wie Teams auf EF Core wechselten weil "das doch Standard ist", und dann drei Monate später Dapper-Calls einbauten weil bestimmte Reports einfach nicht performant zu kriegen waren. Das ist Aufwand für nichts. Entscheid vorher, nicht nachher.

Konstellation 3: Microservices oder API-first mit klaren Bounded Contexts EF Core per Bounded Context, ein DbContext pro Service, klare Ownership. Das funktioniert gut. Was oft schiefgeht: ein einzelner DbContext der die ganze Datenbank abbildet, weil das "einfacher anzufangen" ist. Ich habe in einem Projekt eine AppDbContext-Klasse gesehen mit 47 DbSet-Properties. 47. Das ist keine Abstraktion mehr, das ist ein Spiegel deiner Datenbankstruktur in C# — und das Schlechteste aus beiden Welten.


Was wirklich fehlt — und was du sofort machen kannst

Nick zeigt im Artikel den Change Tracker korrekt. Was er nicht zeigt: die drei Zeilen Code, die in 80 Prozent der KMU-Projekte fehlen und die ich fast immer nachträglich einbaue.

Erstens: AsNoTracking für Read-Only-Queries.

var products = await db.Products
    .AsNoTracking()
    .Where(p => p.Price > 1.00m)
    .ToListAsync();

Das ist kein Micro-Optimierung. Bei 200 geladenen Entitäten pro Request und 50 gleichzeitigen Nutzern reduziert das den Speicherverbrauch messbar und beschleunigt den Query. In dem Maschinenbauer-Projekt oben war das die einzige Änderung — von fünf Sekunden auf unter eine Sekunde. Keine Architekturreform, keine Infra-Investition.

Zweitens: Projektion statt vollständiger Entitäts-Loads.

var productNames = await db.Products
    .Where(p => p.Price > 1.00m)
    .Select(p => new { p.Id, p.Name })
    .ToListAsync();

Wenn du für eine Dropdown-Liste nur Id und Name brauchst, lad nicht alle Felder. Das klingt trivial. In der Praxis passiert es trotzdem ständig nicht, weil die generischen Repository-Pattern die Teams benutzen es nicht erzwingen.

Drittens: Logging aktivieren während der Entwicklung, nicht erst wenn's brennt.

optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

Eine Zeile. Damit siehst du jeden generierten SQL-Statement im Output. Ich sage Entwicklern: schalte das lokal immer an. Du wirst überrascht sein was EF Core manchmal baut. Und du willst es lieber im Entwicklungsprozess sehen als in der Produktion.


Meine Empfehlung

EF Core ist im Mittelstand-Kontext fast immer die richtige Wahl für neue Projekte — mit zwei Bedingungen: Erstens musst du einen Entwickler im Team haben der den Change Tracker versteht, nicht nur LINQ-Queries schreiben kann. Zweitens muss klar sein welche Queries Write-heavy und welche Read-heavy sind, und die Read-heavy Paths müssen von Anfang an mit AsNoTracking und Projektion gebaut werden.

Was ich nicht empfehle: EF Core als Drop-in für eine bestehende Datenbank-Landschaft ohne vorherige SQL-Analyse. Und ich empfehle auch nicht den Ansatz den ich regelmäßig sehe — EF Core für alles nehmen weil das Team es kennt, und dann Dapper für die "schwierigen" Queries einbauen. Entscheid dich für einen primären Ansatz pro Service, und halte ihn durch.

Der Artikel von Nick gibt dir das technische Fundament. Die Frage welche Abstraktion für welches Problem im richtigen Verhältnis zu deinem Team-Kontext steht — die beantwortet kein Getting-Started-Post. Die beantwortest du durch das erste Produktionsproblem, oder vorher durch ehrliche Architekturarbeit.


Der vollständige Original-Beitrag von Nick Chapsas: Getting Started with Entity Framework Core (EF Core)


Wenn du gerade eine .NET-Entscheidung vor dir hast — EF Core vs. Dapper, Code-First vs. bestehende DB, Monolith vs. Services — und willst das in dreißig Minuten durchdenken ohne Beratungs-Bingo: → 30 Min Klartext-Sparring

— Bernhard