C# 在不同于父类ID的子类(继承)上添加PK
这些天来,我一直在使用实体Framwork 6(MVC、VisualStudio 2015、代码优先)进行继承。尝试不同的方面,我发现需要生成一个PrimaryKey来标识子类,与从父类继承的PrimaryKey/ForeignKey分开。 我想发展的想法是:C# 在不同于父类ID的子类(继承)上添加PK,c#,visual-studio,entity-framework,inheritance,ef-code-first,C#,Visual Studio,Entity Framework,Inheritance,Ef Code First,这些天来,我一直在使用实体Framwork 6(MVC、VisualStudio 2015、代码优先)进行继承。尝试不同的方面,我发现需要生成一个PrimaryKey来标识子类,与从父类继承的PrimaryKey/ForeignKey分开。 我想发展的想法是: public class Person { [Key] public int PersonId { get; set; } } public class Student : Person { [Key]
public class Person
{
[Key]
public int PersonId { get; set; }
}
public class Student : Person
{
[Key]
public int StudentId { get; set; }
}
我一直在寻找其他尝试过这个的人,但我什么也没找到。我不确定这是否可能,所以如果有人能帮助我,我会非常感激
谢谢。如果你要描述一个
学生,你必须描述学生.StudentId
和学生.PersonId
的含义,你能给出一个正确的描述吗
在我看来,你想给学生一个主键的新属性的唯一原因是因为这个属性的标识符,而不是因为一个真正正确的含义
在实体框架中建模继承时应使用的方法取决于最常用的查询类型
假设你有三种类型的人:学生、老师和家长。考虑您最常做的查询类型:
你最常问的是有……的学生,还是有……的家长
或者你会经常为那些。。。很少有学生。。。或是那些
(1)主要要求学生…:使用TPC
如果您将继承策略建模为,那么学生、教师和家长将各自拥有自己的表。没有通用的父表。学生拥有的所有父属性都在学生表中,类似的,所有这些父属性也都在教师表中
这种继承策略是最好的,如果你主要要求学生谁。。。对于那些。。。使用TPC询问那些。。。我们只需要一张桌子。询问那些。。。将始终需要将查询结果连接到。。。老师们说。。。还有那些
我发现这是我最常使用的继承策略
(2)主要询问以下人员:使用TPT
如果这些是最常用的查询,最好在单独的表中对所有人员数据进行建模,并让学生、教师和家长都对他们的人员数据有一些参考:
如何实施TPC
如果您根据TPC实现继承,那么就不会有单独的Person表。不需要给人身份证
class Person
{
public string FirstName {get; set;}
...
}
class Student : Person
{
public int Id {get; set;}
...
}
class Teacher : Person
{
public int Id{get; set;
...
}
如果你计划从不实例化一个人,只有学生、老师和家长,那么就声明Person类抽象
顺便说一下,如果您为主键属性指定默认名称Id
,entity framework将知道这应该是您的主键。不需要属性,也不需要fluent API
在您的环境中:
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
}
}
但是,不确定您是否可以仅使用数据注释。。。。你为什么要这么做?有一个统一的PK名称是非常有用的。谢谢你的帮助!!最后实现了(2),我发现如果不在基类上声明PK,那么可以在子类中定义自己的PK。但是你不能用TPT实现这一点,你应该实现TPH
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;}
...
}