简体   繁体   中英

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

I have a question regarding EF6. Let's say I have an abstract base class that looks like this:

[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; }
}

Then there are two entities that inherit 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; }
}

That is all fine here for me. We have some TPH and this is why we got a Discriminator column. OK, fine but my problem are the navigation properties in the table Groups which actually look like this:

[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; }
}

It seems like the navigation properties are responsible for the generation of two columns in the Table Persons that are Named: Group_Id and Group_Id1 which are always empty. I don't need this columns, because in this table there is already a column GroupId with points to Groups . Also the navigation properties are not working, so I think I am doing something wrong.

The table Persons looks like:

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

but I want this table to look like:

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

If I remove the navigation properties everything is OK, but I would love to keep them because they are really handy. Any ideas?

The problem is you are configuring two one-to-many relationships, one between Teacher and Group and the another one between Student and Group , that's way you have two additional FK columns ( Group_Id and Group_Id1 ) in your Persons table. To achieve what you want you need to establish just one relationship between Person and Group this way:

[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; }    
}

Then, if you need to work with students of an specific group you can filter them this way:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM