C# EF6 Code First TPH - 两个使用注释继承同一实体的实体的导航属性

C# EF6 Code First TPH - Navigation properties to two entities who inhrerits the same entity using annotations

我有一个关于 EF6 的问题。假设我有一个抽象基础 class,看起来像这样:

[Table("Persons")]
public abstract class Person
{
    [Key]
    public int Id { get; set; }

    [Required, ForeignKey("Group")]
    public int GroupId { get; set; }

    [Required(AllowEmptyStrings = true), MaxLength(150)]
    public string FirstName { get; set; }

    [Required(AllowEmptyStrings = true), MaxLength(150)]
    public string LastName { get; set; }
}

然后有两个实体继承Person:

[Table("Persons")]
public class Teacher : Person
{
    [Required]
    public int ExpirienceInYears { get; set; }
}

[Table("Persons")]
public class Student : Person
{
    [Required]
    public int Age { get; set; }
}

这对我来说很好。我们有一些 TPH,这就是为什么我们有一个鉴别器列。好的,很好,但我的问题是 table Groups 中的导航属性实际上看起来像这样:

[Table("Groups")]
public class Group
{
    [Key]
    public int Id { get; set; }

    [Required(AllowEmptyStrings = true), MaxLength(150)]
    public string Name { get; set; }

    public virtual ICollection<Teacher> Teachers { get; set; }
    public virtual ICollection<Student> Students { get; set; }
}

导航属性似乎负责在 Table Persons that Named 中生成两列:Group_IdGroup_Id1,它们始终为空。我不需要这些列,因为在这个 table 中已经有一个列 GroupId 指向 Groups。导航属性也不起作用,所以我想我做错了什么。

table Persons 看起来像:

Id |  GroupId | FirstName | LastName | ExpirienceInYears | Age | Discriminator | Group_Id | Group_Id1

但我希望这个 table 看起来像:

Id |  GroupId | FirstName | LastName | ExpirienceInYears | Age | Discriminator

如果我删除导航属性,一切都很好,但我很想保留它们,因为它们真的很方便。有什么想法吗?

问题是您正在配置两个一对多关系,一个在 TeacherGroup 之间,另一个在 StudentGroup 之间,那是你的 Persons table 中有两个额外的 FK 列(Group_IdGroup_Id1)。要实现您想要的效果,您只需要通过这种方式在 PersonGroup 之间建立一种关系:

[Table("Persons")]
public abstract class Person
{
    [Key]
    public int Id { get; set; }
    //...
    [ForeignKey("Group")]
    public int GroupId { get; set; }

    public virtual Group Group { get; set; }
}

[Table("Groups")]
public class Group
{
    [Key]
    public int Id { get; set; }

    //...
    public virtual ICollection<Person> Persons { get; set; }    
}

然后,如果您需要与特定组的学生一起工作,您可以这样过滤他们:

var group=db.Groups.Find(1);//search an specific group
var students=group.Persons.OfType<Student>();// get all the students of that group