Detaillierte Fälle für die Portierung von EF6 zu EF Core

In diesem Dokument werden einige spezifische Unterschiede zwischen EF6 und EF Core erläutert. Orientieren Sie sich bei der Portierung des Codes an diesem Leitfaden.

Konfigurieren der Datenbankverbindung

Es gibt mehrere Unterschiede zwischen der Verbindung von EF6 mit verschiedenen Datenquellen im Vergleich zu EF Core. Es ist wichtig, dass Sie sie kennen, wenn Sie Ihren Code portieren.

  • Verbindungszeichenfolgen: EF Core unterstützt nicht direkt mehrere Konstruktorüberladungen für unterschiedliche Verbindungszeichenfolgen wie EF6. Stattdessen basiert es auf DbContextOptions. Sie können weiterhin mehrere Konstruktorüberladungen in abgeleiteten Typen bereitstellen, müssen Verbindungen jedoch über die Optionen zuordnen.
  • Konfiguration und Cache: EF Core unterstützt eine robustere und flexiblere Implementierung der Dependency Injection mit einer internen Infrastruktur, die eine Verbindung mit externen Dienstanbietern herstellen kann. Dies kann von der Anwendung verwaltet werden, um Situationen zu behandeln, in denen die Caches geleert werden müssen. Die EF6-Version war eingeschränkt und konnte nicht geleert werden.
  • Konfigurationsdateien: EF6 unterstützt die Konfiguration über Konfigurationsdateien, die den Anbieter enthalten können. EF Core erfordert einen direkten Verweis auf die Anbieterassembly und die explizite Anbieterregistrierung (d. h. UseSqlServer).
  • Verbindungsfactorys: EF6 unterstützte Verbindungsfactorys. EF Core unterstützt keine Verbindungsfactorys und erfordert immer eine Verbindungszeichenfolge.
  • Protokollierung: Im Allgemeinen ist Protokollierung in EF Core wesentlich robuster und verfügt über mehrere Optionen für eine fein abgestimmte Konfiguration.

Konventionen

EF6 unterstützte benutzerdefinierte Konventionen („lightweight“) und Modellkonventionen. Die Lightweightkonventionen ähneln der Konfiguration des Präkonventionsmodells von EF Core. Andere Konventionen werden als Teil der Modellerstellung unterstützt.

EF6 führt Konventionen aus, nachdem das Modell erstellt wurde. EF Core wendet sie an, wenn das Modell erstellt wird. In EF Core können Sie die Modellerstellung von aktiven Sitzungen mit einem DbContext entkoppeln. Es ist möglich, ein mit den Konventionen initialisiertes Modell zu erstellen.

Datenüberprüfungen

EF Core unterstützt keine Datenüberprüfung und verwendet Datenanmerkungen nur zum Erstellen des Modells und der Migrationen. Die meisten Clientbibliotheken von web/MVC bis zu WinForms und WPF stellen eine zu verwendende Datenüberprüfungsimplementierung bereit.

In Kürze verfügbare Features

Es gibt einige neue Features in EF6, die noch nicht in EF Core vorhanden sind, sich aber in der Produktroadmap befinden.

  • Tabelle pro konkretem Typ (Table-per-Concrete Type, TPC) wurde in EF6 zusammen mit „Entitätsaufteilung“ unterstützt. TPC ist in der Roadmap für EF7 enthalten.
  • Zuordnung gespeicherter Prozeduren in EF6 ermöglicht Ihnen, Erstellungs-, Aktualisierungs- und Löschvorgänge an gespeicherte Prozeduren zu delegieren. EF Core ermöglicht derzeit nur die Zuordnung gespeicherter Prozeduren für Lesevorgänge. Unterstützung für Erstellen, Aktualisieren und Löschen (Create, Update, Delete – CUD) ist in der Roadmap für EF7 enthalten.
  • Komplexe Typen in EF6 ähneln eigenen Typen in EF Core. Der vollständige Satz von Funktionen wird jedoch in EF7 mit Wertobjekten behandelt.

ObjectContext hinter sich lassen

EF Core verwendet einen DbContext anstelle eines ObjectContext. Sie müssen Code aktualisieren, der IObjectContextAdapter verwendet. Dies wurde manchmal für Abfragen mit der PreserveChanges- oder OverwriteChanges-Zusammenführungsoption verwendet. Schauen Sie sich für ähnliche Funktionen in EF Core die Reload-Methode an.

Modellkonfiguration

Es gibt viele wichtige Unterschiede zwischen dem Entwurf von Modellen in EF6 und EF Core. EF Core bietet keine vollständige Unterstützung der bedingten Zuordnung. Es hat keine Modellgeneratorversionen.

Zu anderen Unterschieden zählen Folgende:

Typermittlung

In EF Core werden Entitätstypen von der Engine auf drei Arten ermittelt:

  • Machen Sie ein DbSet<TEntity> auf Ihrem DbContext verfügbar, wobei TEntity der Typ ist, den Sie nachverfolgen möchten.
  • Verweisen Sie von einer beliebigen Stelle im Code aus auf eine Set<TEntity>.
  • Komplexe Typen, auf die von ermittelten Typen verwiesen wird, werden rekursiv ermittelt (wenn Ihr Blog z. B. auf einen Post verweist und der Blog auffindbar ist, wird auch der Post erkannt)

Assemblys werden nicht auf abgeleitete Typen gescannt.

Zuordnung

Die .Map()-Erweiterung in EF6 wurde durch Überladungen und Erweiterungsmethoden in EF Core ersetzt. Sie können z. B. „.HasDiscriminator()“ zum Konfigurieren von Tabelle pro Hierarchie (TPH) verwenden. Siehe: Modellieren der Vererbung.

Vererbungszuordnung

EF6 unterstützte Tabelle pro Hierarchie (TPH), Tabelle pro Typ (TPT) und Tabelle pro konkrete Klasse (Table-per-concrete-Class, TPC) und ermöglichte die Hybridzuordnung verschiedener Varianten auf unterschiedlichen Hierarchieebenen. EF Core erfordert weiterhin eine Vererbungskette, um in eine Richtung zu modellieren (TPT oder TPH), und der Plan ist, Unterstützung für TPC in EF7 hinzuzufügen.

Siehe: Modellieren der Vererbung.

Attribute

EF6 unterstützte Indexattribute für Eigenschaften. In EF Core werden sie auf Typebene angewendet, die es für Szenarien einfacher machen sollten, die zusammengesetzte Indizes erfordern. EF Core unterstützt keine zusammengesetzten Schlüssel mit Datenanmerkungen (d. h. die Verwendung von „Order“ in ColumnAttribute zusammen mit KeyAttribute).

Weitere Informationen finden Sie unter Indizes und Einschränkungen.

Erforderlich und optional

Bei der EF Core-Modellerstellung konfiguriert IsRequired nur das, was für das Prinzipalende erforderlich ist. HasForeignKey konfiguriert jetzt das Prinzipalende. Um Ihren Code zu übertragen, ist es einfacher, stattdessen .Navigation().IsRequired() zu verwenden. Beispiel:

EF6:

modelBuilder.Entity<Instructor>()
    .HasRequired(t => t.OfficeAssignment)
    .WithRequiredPrincipal(t => t.Instructor);

EF Core 6:

modelBuilder.Entity<Instructor>()
    .HasOne(t => t.OfficeAssignment)
    .WithOne(t => t.Instructor)
    .HasForeignKey<OfficeAssignment>();

modelBuilder.Entity<Instructor>()
    .Navigation(t => t.OfficeAssignment)
    .IsRequired();

modelBuilder.Entity<OfficeAssignment>()
    .Navigation(t => t.Instructor)
    .IsRequired();

Standardmäßig ist alles optional, daher ist es in der Regel nicht erforderlich, .IsRequired(false) aufzurufen.

Unterstützung räumlicher Funktionen

EF Core ist in die Drittanbieter-Communitybibliothek NetTopologySuite integriert, um räumliche Unterstützung zu bieten.

Unabhängige Zuordnungen

EF Core unterstützt keine unabhängigen Zuordnungen (ein EDM-Konzept, mit dem die Beziehung zwischen zwei Entitäten unabhängig von den Entitäten selbst definiert werden kann). Ein ähnliches, in EF Core unterstütztes Konzept sind Schatteneigenschaften.

Migrationen

EF Core unterstützt keine Datenbankinitialisierer oder automatische Migrationen. Obwohl es in EF Core keine migrate.exe gibt, können Sie Migrationsbündel erstellen.

Visual Studio-Tools

EF Core verfügt über keinen Designer, keine Funktionalität zum Aktualisieren des Modells aus der Datenbank und keinen Modell-First-Flow. Es gibt keinen Reverse-Engineering-Assistenten und keine integrierten Vorlagen.

Obwohl diese Features nicht mit EF Core geliefert werden, gibt es OSS-Communityprojekte, die zusätzliche Tools bereitstellen. Insbesondere bietet EF Core Power Tools Folgendes:

  • Reverse Engineering aus Visual Studio heraus mit Unterstützung für Datenbankprojekte (.dacpac). Enthält vorlagenbasierte Codeanpassungen.
  • Sichtprüfung von DbContext mit Modelldiagrammen und Skripterstellung.
  • Verwaltung von Migrationen aus Visual Studio heraus mithilfe einer GUI.

Eine Liste der empfohlenen Communitytools und -erweiterungen finden Sie unter EF Core-Tools und -Erweiterungen.

Änderungsnachverfolgung

Es gibt mehrere Unterschiede zwischen dem Umgang mit der Änderungsnachverfolgung durch EF6 und EF Core. Diese werden in der folgenden Tabelle zusammengefasst:

Feature EF6 EF Core
Entitätszustand Fügt das gesamte Diagramm hinzu/fügt es an Unterstützt Navigationen zu getrennten Entitäten
Verwaiste Elemente Wird beibehalten Gelöscht
Getrennte, selbstnachverfolgende Entitäten Unterstützt Nicht unterstützt
Mutationen Ausgeführt für Eigenschaften Ausgeführt für Unterstützungsfelder*
Datenbindung .Local .Local plus .ToObservableCollection oder .ToBindingList
Änderungserkennung Vollständiges Diagramm Pro Entität

* Standardmäßig wird die Eigenschaftenbenachrichtigung in EF Core nicht ausgelöst, sodass es wichtig ist, Benachrichtigungsentitäten zu konfigurieren.

Beachten Sie, dass EF Core die Änderungserkennung nicht so oft automatisch aufruft wie EF6.

EF Core führt eine detaillierte DebugView für die Änderungsverfolgung ein. Weitere Informationen finden Sie unter Debuggen der Änderungsnachverfolgung.

Abfragen

EF6 verfügt über einige Abfragefunktionen, die in EF Core nicht vorhanden sind. Dazu gehören:

  • Einige allgemeine C#-Funktionen und SQL-Funktionszuordnungen.
  • Abfangen der Befehlsstruktur für Abfragen und Updates.
  • Unterstützung für Tabellenwertparameter (Table-Valued Parameters, TVPs).

EF6 verfügt über integrierte Unterstützung für verzögert ladende Proxys. Dies ist ein Opt-In-Paket für EF Core (siehe Verzögertes Laden zugehöriger Daten).

EF Core ermöglicht Ihnen, mit FromSQL über unformatiertes SQL zu erstellen.