0

Ich frage mich, ob ich virtuelle Eigenschaften in einer Basisklasse (Zusammenfassung) definieren kann, um eine Verknüpfung mit einem anderen konkreten Typ zu erstellen.EF, Tabelle pro Hierarchie, Eigenschaft in abstrakten Klasse

Zum Beispiel:

public abstract class AbstractService 
{ 
    public int Id {get;set;} 

    public int? SiteId {get;set;} 
    public virtual Site Site {get;set;} 
} 

public class StudyTeamService : AbstractService 
{ 
    public int? RoleId {get;set;} 
    public virtual Role Role {get;set;} 
} 


public abstract class AbstractSite 
{ 
    public int Id {get;set;} 

    public string Name {get;set;} 
} 

public class Site : AbstractSite 
{ 
    public virtual ICollection<StudyTeamService> StudyTeamServices {get;set;} 
} 

Ich nehme an Ich habe eine Anmerkung auf der ICollection hinzuzufügen, so dass sie wissen, wie man richtig auf der Karte, aber ich kann die richtigen nicht finden.

Haben Sie eine Idee?

Es scheint, dass, wenn ich gesetzt [InverseProperty („Site“)] auf der ICollection, es Absturz mit einem Fehler zu sagen, dass die Beziehung nicht in der Baugruppe definiert ...

Antwort

1

ich das Problem mit Ihrem Code denke in ist

public class Site : AbstractSite 
{ 
    public virtual ICollection<StudyTeamService> StudyTeamServices {get;set;} 
} 

da die Beziehung zwischen Site and Abstract , not with StudyTeamService` ist.

Der folgende Code funktioniert für mich:

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Data.Entity; 
using System.Data.Entity.ModelConfiguration; 

namespace StackOverflow 
{ 

    public abstract class AbstractService 
    { 
     public int Id { get; set; } 
     public virtual Site Site { get; set; } 

     public int SiteId { get; set; } 
    } 

    [Table("StudyTeamServices")] 
    public class StudyTeamService : AbstractService 
    { 
     public virtual Role Role { get; set; } 
    } 

    public class Role 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 


    public abstract class AbstractSite 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

    public class Site : AbstractSite 
    { 
     public virtual ICollection<AbstractService> StudyTeamServices { get; set; } 
    } 

    public class Context : DbContext 
    { 
     static Context() 
     { 
      Database.SetInitializer<Context>(null); 
     } 

     public DbSet<AbstractService> AbstractServices { get; set; } 
     public DbSet<StudyTeamService> StudyTeamServices { get; set; } 
     public DbSet<Site> Sites { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      //Not EdmMetadata Table on DB 
      //modelBuilder.Conventions.Remove<IncludeMetadataConvention>(); 

      modelBuilder.Configurations.Add(new AbstractServiceMap()); 
     } 

    } 

    public class AbstractServiceMap : EntityTypeConfiguration<AbstractService> 
    { 
     public AbstractServiceMap() 
     { 
      HasRequired(a => a.Site).WithMany(s => s.StudyTeamServices).HasForeignKey(a => a.SiteId); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var context = new Context(); 
      context.Database.Delete(); 
      context.Database.Create(); 

      var studyTeamService = new StudyTeamService(); 
      studyTeamService.Role = new Role { Name = "role1" }; 
      studyTeamService.Site = new Site { Name = "Site1" }; 

      context.StudyTeamServices.Add(studyTeamService); 
      context.SaveChanges(); 
      Console.WriteLine("Done"); 
      Console.ReadLine(); 
     } 
    } 
} 
+0

In der Tat, ich will nicht die Website eine Liste von Abstract haben. Ich möchte, dass die Liste "konkret geschrieben" wird. Da wir 5 Arten von Diensten haben und wir nicht jedes Mal, wenn wir auf sie zugreifen, umwandeln wollen. Deshalb wollen wir, dass sie vom Typ der konkreten Klasse und nicht von der abstrakten Klasse sind. – Whoami

+0

Dann sollten Sie keine öffentliche öffentliche Site Site {get; set;} in 'AbstractService' haben. Setzen Sie es in die konkreten Klassen. 'Site' wird mehrere Sammlungen zu diesen konkreten Klassen haben. Sobald Sie 'public virtual Site Site {get; set;}' in 'AbstractService' geschrieben haben, definieren Sie eine Beziehung zwischen' AbstractService' und 'Site' und (implizit) eine umgekehrte Beziehung zwischen' Site' und seiner Sammlung von 'AbstractService' s. –

+0

Das Problem besteht darin, dass wir im echten Projekt: AbstractService, AbstractPersonService, das AbstractService und AbstractSiteService erweitert, die auch AbstractService erweitern. Und diese Klassen werden um die konkreten Klassen erweitert. Und öffentliche virtuelle Site Site wäre in jedem konkreten Typ. Das ist seltsam, da dies eine Menge Wiederholungen ist und die Vererbung auch dafür gemacht wird ... – Whoami