我有模特人和模特团队。团队有一个FK to Person,可以与Person.PersonId建立一个可空的TeamleaderId和一个虚拟的Person Teamleader {get; set;}。
有几个团队,一些团队领导,一些团队领导。现在我尝试将teamleader属性更改为另一个teamleader。在SaveChanges上,我得到以下异常:“发生了参照完整性约束违规:关系一端的'Personal.PersonalId'的属性值与'Team.TeamleaderId'的属性值不匹配另一端。“
Teamleader和TeamleaderId相互对应,即使将teamleader重置为null也不起作用。
当我第一次在没有领导者的团队中设置团队领导时,一切正常。更改团队领导不再有效。
我做错了什么?
亲切的问候,伴侣
编辑:
以下是模型:
public class Person
{
[Key]
public long PersonId { get; set; }
// some other...
// optional: List of Teams
}
public class Team
{
[Key]
public long TeamId { get; set; }
// some other...
public long? TeamleaderId { get; set; }
[ForeignKey("TeamleaderId")]
public virtual Person Teamleader { get; set; }
}
我还在做一些研究,并会回来......
哇!现在对于一些非常奇怪的人来说:
如果我在监视窗口中查询实体状态,则状态为“已修改”并且记录正确保存。如果我不查询实体状态,当记录到达SaveChanges时状态为“Unchanged”,并且没有任何反应。此时AutoDetectChangesEnabled为true。
这到底是什么意思?
答案 0 :(得分:1)
好的,就是这样。
由于AutoDetectChangesEnabled = true是一个性能杀手,我们在迭代数据库对象并在上下文中添加/更新它时将其关闭。
我们的覆盖SaveChanges遍历context.ChangeTracker.Entries()。其中(修改...)。根据AutoDetectChangesEnabled的设置,Entries()方法调用DbContext.ChangeTracker.DetectChanges()或不调用 - 在这种情况下:DetectChanges被 NOT 调用。
现在我们在迭代DbContext.ChangeTracker.Entries(修改后的......)之前直接手动调用DbContext.ChangeTracker.DetectChanges(),因此
ChangeTracker包含具有正确值的修改记录。
我们自己的迭代/枚举实体没有性能泄漏。 (例如:使用全局激活的AutoDetectChangesEnabled保存具有相当多导航属性的不太多实体需要12秒;仅在SaveChanges中调用DetectChanges将其减少到400毫秒!)。
总结:您可以将AutoDetectChangesEnabled设置为false,您应该这样做(例如,如果您有许多记录或许多导航属性/复杂数据树)。在覆盖SaveChanges时,调用context.ChangeTracker.DetectChanges(),一切都应该正常工作。
HTH,亲切的问候, 伴侣