2016-05-08 3 views
1

Folgende Gesellschaften mein Code zuerst die PersonParameter ist eine abstrakte Klasse und Hemd und Schuhe werden von ihm mit typ geerbt (1,2)Entity Framework-Code ersten zwei Navigation zu/von einer abstrakten Einheit

[Table("Person")] 
public class Person 
{ 
    [Key] 
    public int id { get; set; } 
    public string Name { get; set; } 

    public int? shirtID { get; set; } 
    public int? shoesID { get; set; } 

    [ForeignKey("shirtID")] 
    public Shirt Shirt { get; set; } 
    [ForeignKey("shoesID")] 
    public Shoes Shoes { get; set; } 
} 

[Table("PersonParameter")] 
public abstract class PersonParameter 
{ 
    public int id { get; set; } 
    public string Title { get; set; } 
    public string Value { get; set; } 

    public List<Person> Persons { get; set; } 
} 

public class Shirt : PersonParameter 
{ 

} 
public class Shoes : PersonParameter 
{ 

} 

und für das Modell DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<PersonParameter>() 
     .Map<Shirt>(p => p.Requires("typ").HasValue(1)) 
     .Map<Shoes>(p => p.Requires("typ").HasValue(2)); 
} 

aber die oben genannten Codes werden unerwünschte Feld PersonParameter_id in Person Tabelle erstellen:

public override void Up() 
{ 
    CreateTable(
     "dbo.PersonParameter", 
     c => new 
      { 
       id = c.Int(nullable: false, identity: true), 
       Title = c.String(), 
       Value = c.String(), 
       typ = c.Int(nullable: false), 
      }) 
     .PrimaryKey(t => t.id); 

    CreateTable(
     "dbo.Person", 
     c => new 
      { 
       id = c.Int(nullable: false, identity: true), 
       Name = c.String(), 
       shirtID = c.Int(), 
       shoesID = c.Int(), 
       PersonParameter_id = c.Int(), 
      }) 
     .PrimaryKey(t => t.id) 
     .ForeignKey("dbo.PersonParameter", t => t.shirtID) 
     .ForeignKey("dbo.PersonParameter", t => t.shoesID) 
     .ForeignKey("dbo.PersonParameter", t => t.PersonParameter_id) 
     .Index(t => t.shirtID) 
     .Index(t => t.shoesID) 
     .Index(t => t.PersonParameter_id); 

} 

Wie kann ich es lösen (PersonParameter_id) Ich habe einige FluentApi mit HasOptional.WithMany, aber nicht gelöst.

EDIT
Nach einigen Tests festgestellt, dass für nicht abstrakte Klasse es zu zusätzlicher ID erstellen und die eine Lösung für dieses Problem Festsetzung Navigationseigenschaft von Parameterklasse zu entfernen und auf die Vererbungsklassen (Hemd und Schuhe Hinzufügen)

Antwort

1

Der Grund, warum Sie mit einer zusätzlichen Tabelle FK on Personen enden, liegt an der Eigenschaft Persons in der PersonParameter-Klasse. Grundsätzlich kann EF dies nicht mit einer der beiden aktuellen Beziehungen (Hemd und Schuhe) in Beziehung setzen und hat festgestellt, dass Persons-Eigenschaft eine dritte Beziehung zwischen Personen- und PersonParameter-Tabellen gewesen sein muss, und erstellt daher eine dritte FK (PersonParameter_id), um diese Beziehung zu erstellen. Als Ergebnis erhalten Sie 3 unidirektionale Viele-zu-eins-Beziehungen von PersonParameter zu Personen.

Um das zu beheben, müssen Sie EF ausdrücklich mitteilen, dass Personen die Inverse-Eigenschaft von Shoes and Shirts ist, da es keine Möglichkeit gibt, dass EF das automatisch übernehmen kann. Sie können das mit fließend API tun oder durch Anmerkungen wie folgt aus:

[Table("PersonParameter")] 
public abstract class PersonParameter 
{ 
    public int id { get; set; } 
    public string Title { get; set; } 
    public string Value { get; set; } 
} 

public class Shirt : PersonParameter 
{ 
    [InverseProperty("Shirt")] 
    public List<Person> Persons { get; set; } 
} 

public class Shoes : PersonParameter 
{ 
    [InverseProperty("Shoes")] 
    public List<Person> Persons { get; set; } 
} 


Sie können dies auch erreichen, indem die Fluent API:

modelBuilder.Entity<Shirt>() 
    .HasMany(s => s.Persons) 
    .WithOptional(p => p.Shirt) 
    .HasForeignKey(p => p.shirtID); 

modelBuilder.Entity<Shoes>() 
    .HasMany(s => s.Persons) 
    .WithOptional(p => p.Shoes) 
    .HasForeignKey(p => p.shoesID); 
+0

aber es gibt zwei FK in Person für PersonParameter (ShirtID und ShoesID) also warum braucht es zusätzlichen FK? – Hamid

+0

Danke für den Kommentar. Ich habe meine Antwort entsprechend aktualisiert. –

+0

Danke. Ich habe es vorher gemacht, aber es ist wichtig, dass diese Navigationseigenschaft innerhalb der Hauptklasse (PersonParameter) und nicht innerhalb ihrer Vererbungsklasse liegt, da es eine Basisklasse sein sollte. Auch habe ich einen Test, um öffentliche Liste zu erklären Personen {bekommen; einstellen; } als abstrakte Eigenschaft, und ich glaube, es gibt eine Lösung mit Fluent API, die über diese inversen Eigenschaften aussagt. – Hamid

Verwandte Themen