这些天来,我一直在研究实体框架6的继承(MVC,VisualStudio 2015,代码优先)。从不同的方面尝试,我发现需要生成一个标识子类的PrimaryKey,与从父类继承的primaryKey / ForeignKey分开。
我要发展的想法是这样的:

public class Person
{

    [Key]
    public int PersonId { get; set; }

}

public class Student : Person
{

    [Key]
    public int StudentId { get; set; }

}


我一直在为其他尝试过此方法的人服务,但我什么也没找到。我不确定是否可以这样做,所以如果有人可以帮助我,我将非常感谢

谢谢。

最佳答案

如果您要描述Student,并且必须描述Student.StudentIdStudent.PersonId的含义,您能给出一个适当的描述吗?

在我看来,您要为学生提供主键的新属性的唯一原因是该属性的标识符,而不是真正有意义的含义。

在Entity Framework中为继承建模时应使用的方法取决于您最常使用的查询类型。

假设您有三种类型的人员:学生,教师和父母。考虑您最常执行的查询类型:


您最常会问有...的学生或有...的父母吗?
或者,您最常会这样对待…………的人,而…………………………的学生却很少?


(1)主要要求学生...:使用TPC

如果将继承策略建模为Table per Concrete Class (TPC),则学生,教师和家长将各自拥有自己的表。没有公用的“父母”表。学生表中有学生拥有的所有父级属性,而教师表中也有类似的所有这些父级属性。

如果您主要要求...的学生,而很少要求...的人,则使用这种继承策略是最好的。使用TPC要求...的学生……只需要一张桌子。要求人员...将始终需要对...学生,...教师,...父母的查询结果的串联

我发现这是我最常使用的继承策略。

(2)主要要求...的人:使用TPT

如果这些查询是最常用的查询,则最好在单独的表中对所有“人”数据建模,并让“学生”,“教师”和“家长”都对其“人”数据有一些引用:Table-Per-Type (TPT)

如何实施TPC

如果您根据TPC实现继承,则不会有单独的Person表。无需给人一个ID。

class Person
{
    public string FirstName {get; set;}
    ...
}

class Student : Person
{
    public int Id {get; set;}
    ...
}

class Teacher : Person
{
    public int Id{get; set;
    ...
}


如果您计划从不实例化一个Person,则只有学生,老师和父母可以考虑声明Person类的摘要

顺便说一句,如果为主键属性指定默认名称Id,则实体框架将知道这应该是您的主键。不需要属性,也不需要流畅的API。

在您的DbContext中:

class MyDbContext : DbContext
{
    public DbSet<Student> Students {get; set;}
    public DbSet<Teacher> Teachers {get; set;}
    public DbSet<Parent> Parents {get; set;}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Student>().Map(student =>
        {
            student.MapInheritedProperties();
            student.ToTable(nameof(MyDbContext.Students));
        });

        modelBuilder.Entity<Teacher>().Map(teacher =>
        {
            teacher.MapInheritedProperties();
            teacher.ToTable(nameof(MyDbContext.Teachers));
        });
        // etc. for Parent
    }
}


如何实施TPT

将有一个“人”表,“学生和教师”将参考“人”表。

class Person
{
    public int Id {get;set;}
    ...
}
class Student
 {
    public int Id {get;set;}
    // A student has Person data via foreign key:
    public int PersonId {get; set;}
    public Person Person {get; set;}
    ...
 }
 class Teacher
 {
    public int Id {get;set;}
    // A Teacher has Person data via foreign key:
    public int PersonId {get; set;}
    public Person Person {get; set;}
    ...
 }

10-08 09:18
查看更多