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");
    }
}

EntitySet中的所有对象都必须具有唯一的主>;键

只有当您的DB在People表中包含一行,并且该行已联接到StudentTeacher表时,才会发生这种情况。要发现此有问题的行,请在数据库中运行以下查询:

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的行)可以是StudentTeacher,但不能同时是两者。然而,在撒旦基地没有任何东西可以避免这种情况的发生。它必须是作为测试数据直接在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();