entity framework不更新外键对象

我是Entity Framework的新手,这种行为让我很困惑:

[Table("ClinicProfile")] public class ClinicProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [ForeignKey("ContactData")] public int ContactDataId { get; set; } public ContactData ContactData { get; set; } } [Table("ContactData")] public class ContactData { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } ... } 

插入新实体时一切正常 – ContactData保存到表中并分配外键:

 clinicProfile.ContactData = contactData; SharedContext.Current.Entry(clinicProfile).State = EntityState.Added; SharedContext.Current.SaveChanges(); 

但是当我尝试更新此实体时,ContactData不会获得更新。

 clinicProfile.ContactData = contactData; SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.SaveChanges(); 

我是否必须将ContactData标记为已修改? 或者我只是做错了什么?

EDIT-2 – 答案

如果contactData是数据库中的新对象,则使用此代码,并使用新的对象ID。

 clinicProfile.ContactData = contactData; SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.SaveChanges(); 

如果您只想更新旧的contactData,那么使用此代码是正确的:

 SharedContext.Current.Entry(contactData).State = EntityState.Modified; SharedContext.Current.SaveChanges(); 

编辑 – 扩展代码快照

来自MVC控制器的代码,从页面回发。 参数“clinicProfile”和“contactData”,“adressData”包含有效的Id。

  [HttpPost] [ValidateAntiForgeryToken] public ActionResult Modify(ClinicProfile clinicProfile, ContactData contactData, AdressData adressData) { ViewBag.Id = clinicProfile.Id; if (ModelState.IsValid) { if (clinicProfile.Id != 0) { clinicProfile.ContactData = contactData; clinicProfile.AdressData = adressData; clinicProfile.AdressDataComposed = adressData.ComposeData(); clinicProfile.ContactDataComposed = contactData.ComposeData(); SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.SaveChanges(); Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id); Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id); return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData }); } { clinicProfile.ContactData = contactData; clinicProfile.AdressData = adressData; clinicProfile.AdressDataComposed = adressData.ComposeData(); clinicProfile.ContactDataComposed = contactData.ComposeData(); SharedContext.Current.Entry(clinicProfile).State = EntityState.Added; SharedContext.Current.SaveChanges(); Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id); Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id); return RedirectToAction("Info", new { id = clinicProfile.Id }); } } ViewBag.Id = clinicProfile.Id; return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData }); } 

你刚才放错了外键属性

  [Table("ClinicProfile")] public class ClinicProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int Id { get; set; } //[ForeignKey("ContactData")] here the wrong place public int ContactDataId { get; set; } [ForeignKey("ContactDataId")] // here the correct place public ContactData ContactData { get; set; } } [Table("ContactData")] public class ContactData { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } ... } 

当您要设置外键数据时,可以设置ContactDataId值或从Database中检索ContactData作为对象并在ClinicProfile中设置它

 // according to your data posted later [HttpPost] [ValidateAntiForgeryToken] public ActionResult Modify(ClinicProfile clinicProfile, ContactData contactData, AdressData adressData) { ViewBag.Id = clinicProfile.Id; if (ModelState.IsValid) { if (clinicProfile.Id != 0) { // here you want to tell the SharedContext to attach the contactData to the clinicProfile // you need to retrieve the lastVersion of contactData from db var currentContactData=SharedContext.Current.ContactData.Single(t=>t.Id=contactData.Id); // update the changed data in the currentContactData clinicProfile.ContactData =currentContactData; // instead of contactData; clinicProfile.AdressData = adressData; clinicProfile.AdressDataComposed = adressData.ComposeData(); clinicProfile.ContactDataComposed = contactData.ComposeData(); SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.SaveChanges(); Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id); Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id); return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData }); } { clinicProfile.ContactData = contactData; clinicProfile.AdressData = adressData; clinicProfile.AdressDataComposed = adressData.ComposeData(); clinicProfile.ContactDataComposed = contactData.ComposeData(); SharedContext.Current.Entry(clinicProfile).State = EntityState.Added; SharedContext.Current.SaveChanges(); Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id); Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id); return RedirectToAction("Info", new { id = clinicProfile.Id }); } } ViewBag.Id = clinicProfile.Id; return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData }); } 

//作为评论讨论的结果

如果你想更新contactData,你需要通过将其状态设置为修改来告诉contactData被修改的上下文,正如你在上一篇文章中提到的那样,如果你做了以下工作,它将会起作用:

SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.Entry(contactData).State = EntityState.Modified; SharedContext.Current.SaveChanges();

希望这会对你有所帮助

您只需在更新时设置ContactDataId

 clinicProfile.ContactData = contactData; clinicProfile.ContactDataId = contactData.Id; SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.SaveChanges(); 

如果你设置为现有的ClinicProfile新的ContactData,你应该先将新的ContactData保存到db,然后再使用新的ContactDataId获取新的Id和第三次更新ClinicProfile。

 clinicProfile.ContactDataId = newContactData.Id; SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.SaveChanges(); 

如果要更新现有的ContactData属性,则应仅保存它。

 SharedContext.Current.Entry(existingContactData).State = EntityState.Modified; SharedContext.Current.SaveChanges();