Vererbung von Tabellen pro konkreten Typ (TPC) in Entity Framework 6 (EF6)

8

Um die Verwendung von Tabellen pro Hierarchie (TPH) zu vermeiden, habe ich mir Beispiele angesehen, wie die Vererbung von TPC-Tabellen in meinem Datenbankmodell am besten implementiert werden kann. Ich stieß auf die offizielle Dokumentation und auf dieser artikel .

Im Folgenden sind einige Mock-Up-Klassen mit einfacher Vererbung aufgeführt.

%Vor%

Die DbModelBuilder-Konfigurationen, die für die Beispiele in beiden Artikeln verwendet werden.

%Vor%

Die Anwendung läuft erfolgreich, aber wenn ich zurück zur Datenbank gehe, finde ich drei (3) Tabellen statt der zwei (2), die ich erwartet habe. Nach ein paar Tests scheint die "BaseEntity" -Tabelle erstellt zu sein, wird aber nie benutzt. Alles scheint gut zu funktionieren mit Ausnahme dieser leeren verwaisten Tabelle.

Ich mache mich mit den DbModelBuilder-Konfigurationen herum und entferne schließlich die "BaseEntity" -Konfigurationen, die das erwartete Ergebnis liefern; Zwei (2) Tabellen, von denen jede die richtigen Eigenschaften hat und richtig funktioniert.

Ich mache einen letzten Test, reiße alle DbModelBuilder-Konfigurationen aus, schließe nur die zwei (2) DbSet-Eigenschaften für "Person" und "Business" ein und teste es erneut.

%Vor%

Zu meiner Überraschung baut das Projekt auf, geht in die Datenbank, erstellt nur die zwei Tabellen mit allen Klasseneigenschaften einschließlich der geerbten aus der "BaseEntity" -Klasse. Ich kann CRUD-Operationen ohne Probleme durchführen.

Nachdem ich viele Tests durchgeführt habe, kann ich keine Probleme mit dem letzten Test feststellen, und ich war nicht in der Lage, den doppelten Schlüsselfehler zu reproduzieren, vor dem beide Artikel gewarnt wurden.

  

Die Änderungen an der Datenbank wurden erfolgreich übernommen, aber ein Fehler   trat beim Aktualisieren des Objektkontexts auf. Der ObjectContext könnte sein   in einem inkonsistenten Zustand. Innerer Ausnahmetext: AcceptChanges   kann nicht fortgesetzt werden, da die Schlüsselwerte des Objekts Konflikte mit einem anderen haben   Objekt im ObjectStateManager. Stellen Sie sicher, dass die Schlüsselwerte sind   vor dem Aufruf von AcceptChanges eindeutig.

  1. Ich bin neugierig, warum die Beispiele die MapInheritedProperties-Eigenschaft verwenden. Ist das eine veraltete Methode?
  2. Warum sagen beide Beispiele, dass Konfigurationseigenschaften für "BaseEntity" enthalten sein sollen, aber entweder die DbSet-Eigenschaft oder eine DbModelBuilder-Konfiguration für die "BaseEntity" -Klasse, um eine unbenutzte Tabelle zu erstellen.
  3. In Bezug auf den eindeutigen Schlüsselfehler warnten die Artikel; Ich bin nicht in der Lage, den Fehler zu reproduzieren, und ich habe viele Male mit dem Primärschlüssel als ein Int, der von der Datenbank generiert wird, und eine GUID, die von der Datenbank generiert wird, getestet. Sind die Informationen zu diesem Fehler auch veraltet oder gibt es einen Test, den ich ausführen kann, um den Fehler zu erzeugen?
Nicholas 15.09.2015, 21:51
quelle

2 Antworten

2

Um das alles einfacher zu machen, habe ich den Code verschoben, der TablePerConcrete zu Open Source zwingen soll. Sein Zweck ist, Funktionen zu erlauben, die normalerweise nur in der Fluent-Schnittstelle verfügbar sind (wo Sie viel Code in die OnModelCreating-Methode Ihrer DB-Klasse streuen müssen), um zu attributbasierten Funktionen zu migrieren.

Damit können Sie Folgendes tun:

%Vor%

Erzwingen von TPC, unabhängig davon, was EF aus der Beziehung zwischen Elternklasse und Unterklasse ableiten könnte.

Eine interessante Herausforderung ist hier, dass EF manchmal eine vererbte Id-Eigenschaft mischt, die so eingestellt wird, dass sie mit einem expliziten Wert gefüllt wird, anstatt von der Datenbank generiert zu werden. Sie können sicherstellen, dass dies nicht der Fall ist, indem die Elternklasse die Schnittstelle IId implementiert (was nur besagt: Dies hat eine Id-Eigenschaft), dann markieren Sie die Unterklassen mit [ForcePKId] .

%Vor%

Den Code zu starten, der all das für dich erledigt, ist ziemlich einfach - füge einfach ein paar Zeilen zu deiner Db-Klasse hinzu:

%Vor%

Sie können auf zwei Arten darauf zugreifen:

  1. Über einen einzelnen Text mit allen relevanten Klassen, die in eine einzelne Datei kopiert wurden, hier: Ссылка

  2. Über eine Bibliothek, unsere Brass9.Data, die wir Open Source veröffentlichen. Es hat viele andere EF6-Tools wie Datenmigrationen. Es ist auch besser organisiert, mit Klassen, die wie erwartet in separate Dateien aufgeteilt sind: Ссылка

Chris Moschini 24.11.2015 14:44
quelle
1

Ich benutze Mapping-Klassen, aber nie-mind. Ich löse es so:

%Vor%

Merken - Basisklasse muss abstrakt sein.

    
quelle