[英]How do I correctly update an entity with foreign key in EF?
I went through this answer , but it still gave me the same exception. 我经历了这个答案 ,但仍然给了我同样的例外。 My
DbContext
has Configuration.AudoDetectChangesEnabled = false
and Configuration.LazyLoadingEnabled = true
, in case that makes a difference. 我的
DbContext
具有Configuration.AudoDetectChangesEnabled = false
和Configuration.LazyLoadingEnabled = true
,以防有所不同。 For a simple example, consider the following: 对于一个简单的示例,请考虑以下内容:
public class Employee {
public int Id {get;set;}
public int TitleId {get;set;}
[ForeignKey(nameof(Employee.TitleId))]
public virtual Title Title{get;set;}
}
Query is done with Context.Set<Employee>().Include(nameof(Employee.Title))
. 使用
Context.Set<Employee>().Include(nameof(Employee.Title))
。 In my case, I have an existing Employee
with an existing Title
. 在我的情况下,我有一个现有的
Employee
和一个Title
。 I've updated my entity with a new TitleId
, one that already exists in the database. 我已经使用新的
TitleId
更新了我的实体,该TitleId
已经存在于数据库中。 Then, I update the EntityState
to EntityState.Modified
and call SaveChanges()
. 然后,我将
EntityState
更新为EntityState.Modified
并调用SaveChanges()
。 This gives the following Exception
: 这给出了以下
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.
Okay, so that should be due to a mismatch between the foreign key id and the navigation property. 好的,那应该是由于外键ID与Navigation属性之间的不匹配。 So then I set
Title
to null
prior to setting EntityState
. 因此,在设置
EntityState
之前,我将Title
设置为null
。 Still the same issue. 还是一样的问题。
Next, I've tried detaching the entity prior to setting EntityState.Modified
. 接下来,我尝试在设置
EntityState.Modified
之前分离实体。 Now, saving the entity works, but when I try to load it again, I get a NullReferenceException
on the navigation property. 现在,保存该实体即可,但是当我尝试再次加载它时,在导航属性上得到了
NullReferenceException
。
What's the proper way to do this? 正确的方法是什么?
Do not try to update only the Id property, update the Title entity on the employee instead and the Id property should follow. 不要尝试仅更新Id属性,而是更新员工上的Title实体,然后应遵循Id属性。 So fetch the existing title and student from the db and set the title of the student to the title you fetched from the db.
因此,从数据库中获取现有的标题和学生,然后将学生的标题设置为您从数据库中获取的标题。
Other things i would do differently is using System.Data.Entity and use include with a lambda expression instead to make it more explicit and failsafe. 我会做其他改变的其他事情是使用System.Data.Entity,并使用带有lambda表达式的include来使其更加明确和故障安全。 Like so:
像这样:
Context.Set<Employee>().Include(x => x.Title);
And if i read things right your ForeignKey annotation is obsolote in this case since EF conventions will map to the same name anyway. 如果我没看错,在这种情况下,因为EF约定始终会映射到相同的名称,所以您的ForeignKey注释已过时。 I also think it is a bit of a code smell to have mapping information on the entity.
我还认为在实体上具有映射信息有点代码味道。 Use fluent api instead.
请改用流利的api。 http://www.entityframeworktutorial.net/code-first/foreignkey-dataannotations-attribute-in-code-first.aspx
http://www.entityframeworktutorial.net/code-first/foreignkey-dataannotations-attribute-in-code-first.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.