2016-09-13 5 views
2

Ich versuche TPH-Vererbung mit Entity Framework 6 Code First zu implementieren und habe Probleme mit einer Beziehung von meinen geerbten Typen.Entity Framework-Vererbung und Beziehungen

Mein Code ist

public abstract class Base... 

public class Inherited1 : Base 
{ 
public virtual Type1 Rel { get; set; } 
... 

public class Inherited2 : Base 
{ 
public virtual Type1 Rel {get;set;} 
... 

So die vererbten Typen die "gleiche" Beziehung haben. Die Vererbung selbst funktioniert gut, aber das Problem, das ich habe, ist, dass die Beziehung zu der Tabelle Type1 zweimal hinzugefügt wird (logisch ...) und die andere Beziehung von Inherited2.Id zu Type1.Id statt Inherited2.Type1Id zu Type1.Id dass die erste Beziehung (korrekt) ist.

Ich bin mir nicht sicher, ob es Sinn macht, dies zu erklären und mit dem partiellen Codebeispiel mit geänderten Typennamen, aber ich hoffe, Sie haben es verstanden. Fragen Sie nach weiteren Details, wenn Sie welche benötigen.

Ich könnte wahrscheinlich diese implementieren richtig mit

UPDATE
ich eine Probe Github Repo erstellt haben, das Problem zu demonstrieren. Sag mir einfach, was ich falsch mache. https://github.com/antsim/EntityFrameworkTester

+0

was verwenden Sie? Fließende API oder Anmerkungen? In beiden Fällen zeigen Sie Code, was Sie verwenden – Monah

+0

Die einzige fließende API in Bezug auf diese Beziehungen ist diese modelBuilder.Entity () .HasMany (x => x.Inherited1) .WithRequired (x => x. Typ1) .WillCascadeOnDelete(); –

+0

Ich fügte in meiner Antwort unten die beiden Fälle TPT und TPH für Ihre Referenz hinzu – Monah

Antwort

2

Versuchen Sie, verwenden Sie die folgende

1-, wenn Sie TPT wollen

modelBuilder.Entity<Inherited1>() 
      .ToTable("Inherited1s") 
      .HasKey(x => x.YourKey) 
      .HasRequired(x=>Type1) 
      .WithMany() 
      .HasForeignKey(x=>Type1Id) 
      .WillCascadeOnDelete(false); 

modelBuilder.Entity<Inherited2>() 
      .ToTable("Inherited2s") 
      .HasKey(x => x.YourKey) 
      .HasRequired(x=>Type1) 
      .WithMany() 
      .HasForeignKey(x=>Type1Id) 
      .WillCascadeOnDelete(false); 

2 - wenn Sie TPH wollen

modelBuilder.Entity<Base>() 
      .ToTable("YourTableName") 
      .HasRequired(m=>m.Type1) 
      .WithMany() 
      .HasForeignKey(m=>m.Type1Id) 
      .WillCascadeOnDelete(); // true or false as you want 

für weitere Details können Sie diese überprüfen article

basierend auf der von Ihnen bereitgestellten Probe

  • Attachment und Document aus Datei geerbt und Sie verwenden TPH, die eine Tabelle bedeutet, wird mit einem Discriminator Feld angelegt werden.
  • Document und FileContainer haben eine Beziehung vom Typ 0..1 was bedeutet, ein Fremdschlüssel FileContainerId sollte in den Document daher in der File Tabelle
  • FileContainer und Attachment hat eine Beziehung vom Typ 0..n erstellt wird, dann ein anderes Nullable-Fremdschlüssel wird in der Tabelle Datei

im Beispiel erstellt werden Ihnen zur Verfügung gestellt, machte ich folgende Änderungen

  1. hinzufügen FileContainerId auf dem Tisch Dokument
  2. FileContainerAttachmentId an den Tisch Befestigung
  3. Die auf dem Testcontext hinzufügen war

     modelBuilder.Entity<FileContainer>() 
          .HasOptional(x => x.Document) 
          .WithMany() 
          .HasForeignKey(t => t.DocumentId) 
          .WillCascadeOnDelete(false); 
    
         modelBuilder.Entity<Document>() 
          .HasRequired(t => t.FileContainer) 
          .WithMany() 
          .HasForeignKey(t => t.FileContainerId) 
          .WillCascadeOnDelete(false); 
    
         modelBuilder.Entity<Attachment>() 
          .HasRequired(t => t.FileContainer) 
          .WithMany() 
          .HasForeignKey(t => t.FileContainerAttachmentId) 
          .WillCascadeOnDelete(false); 
    
Änderungen

der Ausgang (Dateitabelle enthält Scheider Feld neben zwei Beziehungen ein richtig war für das Dokument mit dem Container und das andere für den Anhang mit dem Container).

Eine bessere Lösung ist meiner Meinung nach:

  1. Um eine Klasse FileType (Id, Name) mit Werten Attachment, Document, hinzufügen und fügen Sie es als Fremdschlüssel in File
  2. Um nur eine Beziehung 0..n hinzufügen zwischen der FileContainer und File
  3. zu bestätigen, dass nur ein Datensatz in der Datei vom Typ Dokument gleichen Behälter

Hoffe, das wird Ihnen helfen

+0

Sie haben .WithMany im TPH-Beispiel. Ich habe es so funktioniert, aber was, wenn ich 0..1 im Type1 habe? –

+0

0..1 ist ein Sonderfall von 0..n mit n = 1, also kann die gleiche Logik angewendet werden, aber anstelle von HasRequired sollten Sie HasOptional verwenden – Monah

+0

Ich habe ein Github Repo erstellt, um diese Probleme zu reproduzieren und zu testen. Wenn jemand Zeit hat, können sie dort helfen. Ich habe versucht, das gewünschte Ergebnis und aktuelle Probleme in readme.md zu beschreiben. https://github.com/antsim/EntityFrameworkTester –

Verwandte Themen