c# – EF实体在更新时不保存相同实体类型的子属性
我正在使用ASP.NET MVC 5和Entity Framework 6.我有一个页面,允许用户输入流程信息.此信息的一个方面是从下拉启动过程中进行选择.这个类大致如下:
** public class SupportProcess { [Key] public int ProcessId { get; set; } [DisplayName("Starting process?")] public virtual SupportProcess StartProcess { get; set; } public string Name { get; set; } [DisplayName("When is this run?")] public virtual ProcessSchedule ProcessSchedule { get; set; } [DisplayName("")] public string Description { get; set; } [DisplayName("Expected Result")] public string ExpectedResult { get; set; } } ** 我使用的视图模型具有SupportProcess的属性,选定的启动过程以及用于填充视图下拉列表的进程列表. public class SupportProcessViewModel { public SupportProcess SupportProcess { get; set; } public int SelectedStartProcess { get; set; } public List<SupportProcess> Processes { get; set; } public SupportProcessViewModel() { this.SupportProcess = new SupportProcess(); } } 我的编辑帖子操作如下: [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(SupportProcessViewModel vm) { if (ModelState.IsValid) { if (vm.SelectedStartProcess > 0) { vm.SupportProcess.StartProcess = db.SupportProcesses.Find(vm.SelectedStartProcess); } db.Entry(vm.SupportProcess).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(vm); } 问题是,虽然vm.SelectedStartProcess不是null并且具有适当的值,但它永远不会保存到数据库中.数据库将此字段显示为StartProcess_ProcessId.另外值得注意的是,一个进程可能有0或1个启动进程. 我想知道EF是否在数据库表中使这个属性成为一个外键,实际上它指向同一个表,这在某种程度上导致了这个问题.我全都听取了建议. 我还要补充一点,Create Post操作按预期工作.这必须与传达给EF的事情有关,即StartProcess属性也需要在实体上更新.但这是猜测… [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create( SupportProcessViewModel vm) { if (ModelState.IsValid) { if(vm.SelectedStartProcess > 0) { vm.SupportProcess.StartProcess = db.SupportProcesses.Find(vm.SelectedStartProcess); } db.SupportProcesses.Add(vm.SupportProcess); db.SaveChanges(); return RedirectToAction("Index"); } return View(vm); } 解决方法
没有显式原始FK属性的引用导航属性的问题是,影子FK状态由已从中检索实体的DbContext维护.在像您这样的断开连接的场景中丢失哪些信息.
当你调用时 db.Entry(entity).State = EntityState.Modified; 对于断开连接的实体,EF会将实体附加到上下文,并将所有原始属性标记为已修改.参考导航属性被视为未更改,因此在调用SaveChanges时不会更新它们. 要让EF更新FK,了解原始参考属性值和新参考属性值至关重要.在您的情况下,传递的SupportProcess实体的StartProcess属性的原始值. 由于在断开连接的场景中(特别是像你这样的延迟加载属性)你不能依赖传递的对象属性值,我建议以下安全操作序列: (1)将navigation属性设置为null以避免将值附加到上下文. 将它应用于您的案例: [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(SupportProcessViewModel vm) { if (ModelState.IsValid) { // (1) vm.SupportProcess.StartProcess = null; // (2) db.Entry(vm.SupportProcess).State = EntityState.Modified; // (3) db.Entry(vm.SupportProcess).Reference(e => e.StartProcess).Load(); // (4) vm.SupportProcess.StartProcess = vm.SelectedStartProcess > 0 ? db.SupportProcesses.Find(vm.SelectedStartProcess) : null; db.SaveChanges(); return RedirectToAction("Index"); } return View(vm); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |