说我有这个现有架构:
并将此域映射如下:
public class SchoolContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<Subject> Subjects { get; set; }
}
protected override OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().ToTable("People");
modelBuilder.Entity<Student>().ToTable("Students");
}
public abstract class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Student : Person
{
public int StudentId { get; set; }
public string Course { get; set; }
public ICollection<Subject> Subjects { get; set; }
}
public class Subject
{
public int SubjectId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int StudentId { get; set; }
}
我得到一个场景,我需要通过PersonId查询主题,EF会给我一个例外,说'&34;无效的列名&#39; Student_PersonId&#39;&#34;。
我理解EF不能很好地看到FK并且我选择将Person类作为基类,因为我有机会拥有一个教师表,其中它是一个人同样。
请注意,学生表需要有自己的主键,并且只是说架构的设计关系为:
人 - &gt;学生(一对一或一对关系) 学生 - &gt;主题(一对多关系)
有没有办法解决这个问题?另请注意,如果它是使用Code-First制作的,EF会在Students表上省略StudentId,而且我确实有一个现有的数据库
答案 0 :(得分:0)
您应该首先阅读有关实体框架中TPT的this文章。现在你没有'学生是一个人'的关系,你必须将一些东西改成你的数据库才能工作。
abstract
基类。每个学生,老师......都是一个人,这就是为什么你不能拥有学生/老师的DbSet ......他们是人,所以DbSet<Person>
就是你所需要的。Person p = context.Students.FirstOrDefault();
是完全有效的TPT代码。话虽如此,如果您认为Person可以拥有自己的实例(因此某些人没有派生类),您不应该选择TPT并且只使用外键访问person表,就像您一样现在。如果您确实想要使用TPT,则必须进行上述调整。