我首先面临实体框架代码和继承问题。这是我的模特:
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");
}
}
答案 0 :(得分:1)
只有当您的数据库在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
,但不能同时为{{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();