2013-03-27 15 views
6

Przebacz mi, jeśli to pytanie zostało gdzieś odebrane, ciężko mi było znaleźć rozwiązanie tego problemu.Entity Framework Code First Wiele do wielu relacji i dziedziczenia

Próbuję skonfigurować kod EF na początku projektu MVC4. Mam użytkownika i klienta, którzy dziedziczą po osobie. Następnie mam obiekt szablonu, który ma relację wiele do wielu z klientem i relację jeden do wielu z użytkownikiem. Oto jak mam go skonfigurować:

MODELS

public class Person 
{ 
    [Key] 
    public int PersonID { get; set; } 

    public string LastName { get; set; } 
    public string FirstName { get; set; } 

    public string FullName 
    { 
     get 
     { 
      return String.Format("{0} {1}", FirstName, LastName); 
     } 
    } 

    public string Email { get; set; } 

    public virtual List<Template> Templates { get; set; } 
} 

public class User : Person 
{ 
    .... 
} 

public class Customer : Person 
{ 
    .... 
} 

public class Template 
{ 
    public int TemplateId { get; set; } 
    public string TemplateName { get; set; } 

    public virtual List<Customer> Customers { get; set; } 

    [ForeignKey("User")] 
    public int UserId { get; set; } 
    public virtual User User { get; set; } 
} 

KONTEKST

public class ProjectContext : DbContext 
{ 
    public ProjectContext() 
     : base("name=ProjectDB") 
    { 
    } 

    public DbSet<Template> Templates { get; set; } 
    public DbSet<User> Users { get; set; } 
    public DbSet<Customer> Customers { get; set; } 
    public DbSet<Person> People { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions 
      .Remove<PluralizingTableNameConvention>(); 

     modelBuilder.Entity<Template>() 
      .HasMany(x => x.Customers) 
      .WithMany(x => x.Templates) 
      .Map(x => x.MapLeftKey("TemplateId") 
       .MapRightKey("PersonId") 
       .ToTable("TemplateCustomer") 
      ); 
    } 
} 

Jeśli usunąć osoba DBSet z kontekstu to działa dobrze, ale ustawia TPT dziedzictwo. Chciałbym korzystać z dziedziczenia TPH, ale gdy włączam migracje za pomocą Person DBSet w kontekście, dławi się:

"Szablony" NavigationProperty nie są poprawne. Wpisz "MvcProject.Models.Customer" z FromRole "Template_Customers_Target" w AssociationType "MvcProject.Models.Template_Customers" musi dokładnie odpowiadać typowi "MvcProject.Models.Person", na którym zadeklarowano tę właściwość NavigationProperty.

Gdzie ja się tu mylę?

Odpowiedz

14

Nie można dziedziczyć właściwości nawigacyjnych z jednostki bazowej. Zawsze muszą być zadeklarowane jako w klasie, do której odnosi się drugi koniec związku.

  • Template.Customers jest refering Customer (nie do Person), stąd odwrotność nieruchomość nawigacja Templates muszą być zadeklarowane w Customer (nie w Person)
  • Template.User jest refering User (nie do Person), stąd odwrotność nieruchomość nawigacja Templates muszą być zadeklarowane w User (nie w Person)

Tak więc, w zasadzie należy przenieść kolekcję Templates z Person do obu klas pochodnych:

public class Person 
{ 
    // no Templates collection here 
} 

public class User : Person 
{ 
    //... 
    public virtual List<Template> Templates { get; set; } 
} 

public class Customer : Person 
{ 
    //... 
    public virtual List<Template> Templates { get; set; } 
} 

Następnie można zdefiniować dwie relacje z Fluent API tak:

modelBuilder.Entity<Template>() 
    .HasMany(t => t.Customers) 
    .WithMany(c => c.Templates) // = Customer.Templates 
    .Map(x => x.MapLeftKey("TemplateId") 
       .MapRightKey("PersonId") 
       .ToTable("TemplateCustomer")); 

modelBuilder.Entity<Template>() 
    .HasRequired(t => t.User) 
    .WithMany(u => u.Templates) // = User.Templates 
    .HasForeignKey(t => t.UserId); 
0

Zmień selektor hasMany do ludu:

modelBuilder.Entity<Template>() 
     .HasMany(x => x.People) // here 
     .WithMany(x => x.Templates) 
     .Map(x => x.MapLeftKey("TemplateId") 
      .MapRightKey("PersonId") 
      .ToTable("TemplateCustomer") 
     ); 
+0

W tym celu chciałbym Muszę zmienić listę klientów na listę osób. To pokonałoby cel, potrzebuję wielu do wielu relacji z Szablonem i Osobą. – ferics2

Powiązane problemy