EF6 TPT外键问题

时间:2016-01-28 15:38:33

标签: entity-framework entity-framework-6

说我有这个现有架构:

enter image description here


并将此域映射如下:

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,而且我确实有一个现有的数据库

1 个答案:

答案 0 :(得分:0)

您应该首先阅读有关实体框架中TPT的this文章。现在你没有'学生是一个人'的关系,你必须将一些东西改成你的数据库才能工作。

  1. 学生的主键同时应该是人员表的外键。由于学生一个人,因此它将该数据库作为其基类,而Student表应该只包含学生的特定属性。 Person的属性是继承的。
  2. Person是您的abstract基类。每个学生,老师......都是一个人,这就是为什么你不能拥有学生/老师的DbSet ......他们是人,所以DbSet<Person>就是你所需要的。
  3. 您无法将人物映射到表格。如果你真的想要TPT 每个的人也是老师,学生......一个人不应该存在,所以你不应该把它映射到一个表。课程是抽象的,你不能只有一个人。例如,Person p = context.Students.FirstOrDefault();是完全有效的TPT代码。
  4. 话虽如此,如果您认为Person可以拥有自己的实例(因此某些人没有派生类),您不应该选择TPT并且只使用外键访问person表,就像您一样现在。如果您确实想要使用TPT,则必须进行上述调整。