c# - 在与父类 ID 不同的子类(继承)上添加 PK

标签 c# visual-studio entity-framework inheritance ef-code-first

这几天一直在研究Inheritance with Entity Framwork 6(MVC, VisualStudio 2015, code-first)。尝试不同的方面,我发现需要生成一个标识子类的 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 的含义,您能给出适当的描述?

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

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

假设您有三种类型的人:学生、教师和家长。考虑您最常执行的查询类型:

  1. 您最常询问的学生有...,还是家长有...
  2. 或者,对于那些……的人,您最常会这样,而对于那些……的学生,或者那些……的老师,您会很少吗?

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

如果您将继承策略建模为 Table per Concrete Class (TPC) ,然后学生、教师和家长将各自拥有自己的表格。没有公共(public)的 Parents 表。 Student 拥有的所有 Parent 属性都在 Students 表中,类似的所有这些 Parent 属性也在 Teachers 表中。

如果您主要询问 Students who... 而很少询问 Persons that... 使用 TPC 询问 Students who... 将只需要一张表,则此继承策略是最好的。询问 Persons that... 总是需要串联查询 Students who... 和 Teachers that... 以及 Parents who... 的查询结果

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

(2) MoSTLy ask for Persons who...: Use TPT

如果这些是最常用的查询,最好将所有人员数据建模在一个单独的表中,让学生、教师和家长都可以引用他们的人员数据:Table-Per-Type (TPT)

如何实现TPC

如果按照TPC实现继承,那么就不会有单独的Person表了。不需要给 Persons 一个 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,只有 Students、Teachers 和 Parents,condsder 声明 Person 类抽象

顺便说一句,如果您为主键属性指定默认名称 Id, Entity Framework 将知道这应该是您的主键。不需要属性,也不需要流畅的 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

会有一个Persons表,Students和Teachers会引用Persons表。

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

关于c# - 在与父类 ID 不同的子类(继承)上添加 PK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45756067/

相关文章:

c# - 如何抽象出不同的 JSON 库实现

c# - 如何使用 Linq 表达式树从 Span<T> 中获取值?

visual-studio - 如何在 Visual Studio Team Services 生成定义中对程序集进行签名

c# - Entity Framework - 同时执行多个查询时出错

c# - 在 C# 中使用带有默认命名空间的 Xpath

C# MongoDB 字段映射

c++ - 无法打开文件 'd3d9.h' - Windows 10/DirectX 9/VS 2015

.net - 2008 年和 2010 年项目文件之间是否有任何实际(重大)更改?

c# - 具有自定义端点名称的 WEB API .NET 操作

c# - 无法查询 EF 对象上名为 "group"的属性