如何在EF中使用外键正确更新实体?

时间:2017-11-07 14:45:32

标签: c# entity-framework

我经历了这个answer,但它仍然给了我同样的例外。我的DbContextConfiguration.AudoDetectChangesEnabled = falseConfiguration.LazyLoadingEnabled = true,以防万一。举一个简单的例子,请考虑以下内容:

public class Employee {
    public int Id {get;set;}
    public int TitleId {get;set;}

    [ForeignKey(nameof(Employee.TitleId))]
    public virtual Title Title{get;set;}
}

使用Context.Set<Employee>().Include(nameof(Employee.Title))完成查询。在我的情况下,我现有Employee现有Title。我已使用新的TitleId更新了我的实体,该EntityState已存在于数据库中。然后,我将EntityState.Modified更新为SaveChanges()并致电Exception。这给出了以下A referential integrity constraint violation occurred: The property value(s) of 'Employee.TitleId' on one end of a relationship do not match the property value(s) of 'Title.Id' on the other end.

Title

好的,这应该是由于外键id和导航属性不匹配造成的。因此,在设置null之前,我将EntityState设置为EntityState.Modified。仍然是同一个问题。

接下来,我在设置NullReferenceException之前尝试分离实体。现在,保存实体可以工作,但是当我尝试再次加载它时,我在导航属性上得到app.security.voter.grade: class: AppBundle\Security\Voter\GradeVoter tags: - { name: security.voter }

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

不要尝试仅更新Id属性,而是更新员工的Title实体,然后应该遵循Id属性。因此,从数据库中获取现有的标题和学生,并将学生的标题设置为从数据库中提取的标题。

我会做的其他事情是使用System.Data.Entity并使用带有lambda表达式的include来使其更加明确和故障安全。像这样:

 Context.Set<Employee>().Include(x => x.Title);

如果我正确地读了你的东西,那么在这种情况下你的ForeignKey注释是偶然的,因为无论如何EF约定将映射到同一个名字。我还认为在实体上有映射信息有点代码味道。请使用流畅的api代替。 http://www.entityframeworktutorial.net/code-first/foreignkey-dataannotations-attribute-in-code-first.aspx