Modellierung polymorpher Assoziationen Datenbank-First vs Code-First

Wir haben eine Datenbank, in der eine Tabelle Datensätze enthält, die mehreren anderen Tabellen untergeordnet sein können. Es hat einen "weichen" Fremdschlüssel, der aus der ID des Besitzers und einem Tabellennamen besteht. Dieses (Anti) Muster wird als "polymorphe Assoziationen" bezeichnet. Wir wissen, dass es nicht das beste Datenbankdesign überhaupt ist und werden es zu gegebener Zeit ändern, aber nicht in naher Zukunft. Lassen Sie mich ein vereinfachtes Beispiel zeigen:

BeideEvent, Person, undProduct Einträge im Kommentar haben. Wie Sie sehen, gibt es keine harten FK-Einschränkungen.

In Entity Framework ist es möglich, dieses Modell durch Subklassifizierung zu unterstützenComment inEventComment usw. und lassenEvent einen habenEventComments Sammlung usw .:

Die Unterklassen und die Zuordnungen werden manuell hinzugefügt, nachdem das Grundmodell aus der Datenbank generiert wurde.OwnerCode ist der Diskriminator in diesemTPH Modell. Bitte beachte, dassEvent, Person, undProduct sind völlig verschiedene Einheiten. Es ist nicht sinnvoll, eine gemeinsame Basisklasse für sie zu haben.

Dies ist Datenbank zuerst. Unser reales Modell funktioniert so, kein Problem.

OK. Jetzt wollen wir zuerst zum Code übergehen. Also begann ich mit der Rückentwicklung der Datenbank in ein Code-First-Modell (EF Power Tools) und fuhr fort, die Unterklassen zu erstellen und die Assoziationen und die Vererbung zuzuordnen. Es wurde versucht, eine Verbindung mit dem Modell in Linqpad herzustellen. Zu diesem Zeitpunkt begannen die Probleme.

Beim Versuch, eine Abfrage mit diesem Modell auszuführen, wird einInvalidOperationExeception

Die Fremdschlüsselkomponente 'OwnerId' ist keine deklarierte Eigenschaft des Typs 'EventComment'. Stellen Sie sicher, dass es nicht explizit aus dem Modell ausgeschlossen wurde und dass es sich um eine gültige primitive Eigenschaft handelt.

Dies passiert, wenn ich bidirektionale Assoziationen habe undOwnerId wird als eine Eigenschaft in abgebildetComment. Die Zuordnung in meinemEventMap Klasse (EntityTypeConfiguration<Event>) sieht aus wie das:

this.HasMany(x => x.Comments).WithRequired(c => c.Event)
    .HasForeignKey(c => c.OwnerId);

Also habe ich versucht, den Verein ohne abzubildenOwnerId im Modell:

this.HasMany(x => x.Comments).WithRequired().Map(m => m.MapKey("OwnerId"));

Dies wirft einMetaDataException

Das angegebene Schema ist ungültig. Fehler: (10,6): Fehler 0019: Jeder Eigenschaftsname in einem Typ muss eindeutig sein. Der Eigenschaftsname 'OwnerId' wurde bereits definiert. (11,6): Fehler 0019: Jeder Eigenschaftsname in einem Typ muss eindeutig sein. Der Eigenschaftsname 'OwnerId' wurde bereits definiert.

Wenn ich zwei der drei Entity-Comment-Assoziationen entferne, ist das in Ordnung, aber das ist natürlich keine Heilung.

Einige weitere Details:

Es ist möglich, ein funktionierendes DbContext-Modell ("Code-Sekunde") aus dem edmx zu erstellen, indem ein DbContext-Generatorelement hinzugefügt wird. (Dies wäre vorerst ein Workaround).Wenn ich das funktionierende Code-First-Modell (mit einer Assoziation) nach edmx exportiere (EdmxWriter) Die Assoziation scheint im Speichermodell zu sein, während sie im ursprünglichen EDMX Teil des konzeptionellen Modells ist.

Also, wie kann ich dieses Modell zuerst erstellen? Ich denke, der Schlüssel ist, wie man Code-First anweist, die Assoziationen im konzeptuellen Modell und nicht im Speichermodell abzubilden.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage