Den Ef core DbContext verstehen ist essentiell, um mit dem EF effektiv arbeiten zu können.
Dafür schauen wir uns die Hauptaufgaben und Funktionen des DbContext in diesem Post einmal an.
Mit dem Verständnis des DbContext können wir dann alle anderen Themen im Bezug auf EF core angehen.
Alle Beispiele werden anhand der Beispielapplikation dargestellt.
Aufgaben des DbContext
Eine kurze Übersicht über die Aufgaben des DbContext. Details folgen dann im Verlauf des Posts.
- DbContext Klasse
- Definition der Entitäten
- Konfiguration
- DbContext Instanz
- Eine Instanz dient als Session mit der Datenbank
- Zugang zur Database Facade
- Unit of Work Pattern Abstraction
- Query / Command API offen legen
- CLI
- Beim DbFirst Ansatz
- Migrationen
- Database update
Der DbContext wird in unser Applikation verfügbar, indem wir unsere Contextklasse davon ableiten lassen.
Für gewöhnlich nutzen wir diese zum konfigurieren unserer Entitäten, des Datenbankproviders und zum Bereitstellen der DbSet
DbContext Klasse
Die DbContext Klasse bietet zwei virtual protected Methoden an, die wir zum Konfigurieren überschreiben können:
1.) void OnConfiguring(DbContextOptionsBuilder options) 2.) void OnModelCreating(ModelBuilder modelBuilder)
1.) Diese Methode wird genutzt um:
- Den Datenbankprovider auszuwählen
- Den ConnectionString anzugeben
- Logging zu konfigurieren (oder allg. EF Core features definieren)
- Datenbankprovider spezifische Optionen auszuwählen
2.) Die zweite Methode dient dazu unsere Entitäten zu definieren.
Siehe dazu auch den Code-First approach.
DbContext Instanz
Als Session mit der Datenbank wollen wir es immer schließen, um keine Connections offen zu lassen.
Dafür verwenden wir üblicherweise das using statement in .Net.
Es sei hierbei zusätzlich angemerkt, dass eine DbContext Instanz nicht Thread safe ist!
Um dieses Problem zu umgehen, sollte man pro Thread nur einen DbContext verwenden. In Asp.Net core z.B. ist es ratsam die transient Beziehung für den Context im DI Container zu definieren. Grundsätzlich würde Scoped auch funktionieren, kann aber unter Umständen zu Schwierigkeiten führen.
Bei der Verwendung der asynchronen Methoden auf dem DbContext ist es außerdem wichtig diese ordnungsgemäß mit await abzuwarten, bevor die nächste gestartet wird.
Mit dieser Instanz können wir dann die unterschiedlichen Query API Methoden aufrufen, die wir im LINQ Namespace finden.
- Abfrage:
- Filtern/Sortieren: Where, OrderBy, Include usw.
- Gruppieren/Projektion: Select, Join, GroupBy
- Query Ausführung: Count, Any, All, ToList, ToArray uvm.
- Insert/Update/Delete
- SaveChanges (Unit of Work abstraction)
Ein weiterer wichtiger Aspekt der DbContext Instanz ist die DatabaseFacade Property.
Diese gibt uns Zugang zu folgenden interessanten (low level Database) API Methoden:
- Migrate – Letzte Migration vom Code ausführen
- EnsureCreated/Deleted – Erstellen/Entfernen der DB wenn nicht erstellt/entfernt
- Transaktionsmanagement – Rollback, Commit, Ensure usw.
- ExecuteSQLCommand – Command direkt ausführen
- ExecuteSQL
- OpenConnection
- usw.
Weiterhin können wir über die Instanz auf das ChangeTracking zugreifen. Die gleichnamige Property öffnet uns die Changetracking API. Die ist aber Inhalt eines anderen Posts
Die dritte interessante Property ist die Model Property. Diese gibt uns Zugang zu den Schema Informationen des gegenwärtigen Ef core Models.
Im folgenden Teil sehen wir uns an, wie wir den DbContext im Zug des dotnet ef CLI Tools einsetzen können..
DbContext im dotnet ef CLI Tool
Im CLI Tool mit dotnet ef core fällt einem als erstes die Nutzung im Db First Zusammenhang ein.
Hierbei verwendet man die dotnet ef cli wie folgt, um den DbContext und die POCOs aus der bestehenden Datenbank abzuleiten:
dotent ef dbcontext scaffold $connectionString $Provider \
-c $DbContextName \
--context-dir ./DataAccess
db first helper url:
Ef core- Database First Ansatz
Eine weitere Nutzung mit der CLI ist das Spezifizieren des Context in den folgenden Commands
dotnet ef database update -c $DbContext
#oder auch
dotnet ef migrations add -c $DbContext...
Dies ist insbesondere dann sinnvoll, wenn es mehr als einen DbContext in einem Projekt gibt.
Zusammenfassung
Der DbContext liefert sowohl zur Designtime als auch zur Runtime wichtige Dienste für die Nutzung des Entity Frameworks.
Dies fängt an mit der Definition der Entitäten über die Konfiguration des Datenbankproviders in der Klasse.
Mit einer Instanz des DbContext können wir dann auf die APIs zugreifen. Diese schließen die Query API sowie low level APIs der Datenbank genauso ein, wie das manuelle Verwenden des ChangeTrackings und dem Zugriff auf das Model Schema während der Laufzeit.
Siehe auch hier:
Entity Framework Core
0 Comments