简体   繁体   中英

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. 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)) . In my case, I have an existing Employee with an existing Title . I've updated my entity with a new TitleId , one that already exists in the database. Then, I update the EntityState to EntityState.Modified and call SaveChanges() . This gives the following 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. So then I set Title to null prior to setting EntityState . Still the same issue.

Next, I've tried detaching the entity prior to setting EntityState.Modified . Now, saving the entity works, but when I try to load it again, I get a NullReferenceException on the navigation property.

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. 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. 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. I also think it is a bit of a code smell to have mapping information on the entity. Use fluent api instead. http://www.entityframeworktutorial.net/code-first/foreignkey-dataannotations-attribute-in-code-first.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM