EntitySet中的所有对象都必须具有唯一的主>;键
本文关键字:唯一 gt 对象 EntitySet | 更新日期: 2023-09-27 18:25:18
我面临着实体框架代码优先和继承的问题。这是我的型号:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Student : Person
{
// Student properties
}
public class Teacher : Person
{
// Teacher properties
}
这3个类被映射到具有实体框架的3个表中。它们中的每一个都有一列«Id»(每种类型的表)。到目前为止,这一切都很顺利。
问题是学生也可以是老师。当我试图在同一DbContext中同时获取Student和Teacher对象时,我会得到错误:
EntitySet"Context.People"中的所有对象都必须具有唯一的主对象键。但是,类型为"Student"的实例和类型为教师的主键值相同。
有办法解决这个问题吗?
编辑:以下是关于我的代码的更多详细信息:
using(var context = new CoreContext())
{
var testStudents = context.Students.ToList();
var testTeachers = context.Teachers.ToList();
}
(调用context.Tachers.ToList()时出错)
public class CoreContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Teacher> Teachers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PersonMap());
modelBuilder.Configurations.Add(new StudentMap());
modelBuilder.Configurations.Add(new TeacherMap());
}
}
internal class PersonMap: EntityTypeConfiguration<Person>
{
public PersonMap()
{
this.HasKey(i => i.Id);
this.Property(i => i.Id).HasColumnName("Id");
this.Property(i => i.Name).HasColumnName("Name");
this.ToTable("People");
}
}
internal class StudentMap : EntityTypeConfiguration<Student>
{
public StudentMap()
{
this.ToTable("Students");
}
}
internal class TeacherMap : EntityTypeConfiguration<Teacher>
{
public TeacherMap()
{
this.ToTable("Teachers");
}
}
只有当您的DB在People
表中包含一行,并且该行已联接到Student
和Teacher
表时,才会发生这种情况。要发现此有问题的行,请在数据库中运行以下查询:
Select P.Id
from People P
left join Students S on P.Id = S.Id
left join Teachers T on P.Id = T.Id
where S.Id is not null and T.Id is not null
如果此查询返回条目,则它们必须是直接在DB中创建的。EF不可能做到。
说明:在继承层次结构中,一个人(People
的行)可以是Student
或Teacher
,但不能同时是两者。然而,在撒旦基地没有任何东西可以避免这种情况的发生。它必须是作为测试数据直接在DB中创建的,或者是使用不同的继承层次结构创建的,后来进行了更改。
您可能需要指定更像的内容
public Abstract class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CoreContext : DbContext
{
public DbSet<Person> Person { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PersonMap());
modelBuilder.Configurations.Add(new StudentMap());
modelBuilder.Configurations.Add(new TeacherMap());
}
}
var testStudents = context.Person.OfType<Students>().ToList();
var testTeachers = context.Person.OfType<Teacher>().ToList();