我有这些模特:
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
public class Student : Person
{
public int Payment { get; set; }
}
public class Teacher : Person
{
public int Wage { get; set; }
}
在数据库中,我有两个名为Teachers
和Students
的表。我想使用Entity Framework的TPC映射。我的上下文类是:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.Property(i => i.PersonId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Teacher>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Teacher", "dbo");
});
modelBuilder.Entity<Student>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Student", "dbo");
});
}
但是当我想添加老师时,我收到了这个错误:
已成功提交对数据库的更改,但更新对象上下文时发生错误。 ObjectContext可能处于不一致状态。内部异常消息:AcceptChanges无法继续,因为对象的键值与ObjectStateManager中的另一个对象冲突。在调用AcceptChanges之前,请确保键值是唯一的。
这里有什么问题?
答案 0 :(得分:3)
请参阅此link:
我们得到此异常的原因是因为DbContext.SaveChanges() 在内部调用其内部ObjectContext的SaveChanges方法。 默认情况下,ObjectContext的SaveChanges方法默认调用 在执行数据库修改后接受AcceptAllChanges。
AcceptAllChanges方法仅迭代所有条目 ObjectStateManager并在每个上调用AcceptChanges。以来 实体处于已添加状态,AcceptChanges方法替换它们 具有基于主键的常规EntityKey的临时EntityKey 从数据库返回的值(即PersonId) 这就是问题发生的地方,因为两个实体都是 数据库为其主键分配了相同的值(即打开 PersonId = 1)和问题是ObjectStateManager 无法跟踪相同类型的对象 因此它抛出相同的EntityKey值。如果你仔细看看 上面的TPC的SQL模式,你会看到为什么数据库生成的相同 主键的值:两者中的PersonId列 学生和教师表已被标记为身份。
试试这个:
public srting PersonId { get; set; }
并将配置更改为:
modelBuilder.Entity<Person>()
.Property(i => i.PersonId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
并将您的班级更改为abstract
/