EntitySet中的所有对象必须具有唯一的主要>密钥

时间:2015-12-02 14:10:01

标签: c# entity-framework inheritance

我首先面临实体框架代码和继承问题。这是我的模特:

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

2 个答案:

答案 0 :(得分:1)

只有当您的数据库在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,但不能同时为{{1}}或{{1}}。但是,数据库中没有任何内容可以避免这种情况发生。它必须直接在DB中作为测试数据创建,或者使用不同的继承层次结构创建,后来更改了。

答案 1 :(得分:0)

您可能需要指定更多类似内容

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();