更新FK时违反参照完整性约束

时间:2016-11-04 17:01:28

标签: entity-framework referential-integrity

我有模特人和模特团队。团队有一个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。

这到底是什么意思?

1 个答案:

答案 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,亲切的问候, 伴侣