实体框架不更新外键对象
本文关键字:对象 更新 框架 实体 | 更新日期: 2023-09-27 18:28:01
我是实体框架的新手,这种行为让我很困惑:
[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是DB中的新对象,则使用此代码。
clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
如果你只想更新旧的contactData,那么使用以下代码是正确的:
SharedContext.Current.Entry(contactData).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
EDIT-扩展代码快照
代码来自MVC控制器,从页面回发。参数"clinicProfile"answers"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值,也可以从数据库中检索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();
如果您将新的ContactData设置为现有的ClinicProfile,则应首先将新的Contact Data保存到数据库,然后获取其新Id,第三次使用新的ContactDataId更新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();