【发布时间】:2020-12-06 18:06:58
【问题描述】:
我看到了关于这个相同错误的其他问题,但我无法用我的代码中的这些建议来纠正错误;我认为这是一个不同的问题,而不是重复的。
我有一个应用程序,它制定了一系列规则,用户可以在 GUI 中设置这些规则的属性。在连接的数据库中有一个规则表,主键在 Rule.Id 上。当用户保存对规则的更改时,现有规则将获取“IsActive=0”以隐藏它,然后创建一个新的数据库记录,并将 GUI 中的属性写入数据库。用户看起来好像他们已经编辑了规则,但数据库实际上看到了一个反映新属性的新规则(这允许保留历史记录),通过另一个参考字段连接到旧规则。
在应用程序的 C# 代码中,每个规则的视图模型都包含一个 EF 规则对象属性。当用户单击“保存”时,我使用视图中设置的参数为他们要保存的每个 ruleViewModel 构建ruleViewModel.Rule,并使用与 GUI 匹配的属性。 MainViewModel 包含名为dbo 的DbContext 对象,因此我使用ruleViewModel.Rule 写入我保存到实体框架的mainViewModel.dbo.Entry。以下是为每个可保存的规则视图模型执行的三个基本步骤:
// get the rule from the GUI and use it to make sure we are updating the right rule in EF (which is connected to the mainViewModel)
var dboItem = ruleViewModel.MainViewModel.dbo.Rules.Single(r => r.Id == ruleViewModel.Rule.Id);
// set the values in the EF item to be those we got from the GUI
ruleViewModel.MainViewModel.dbo.Entry(dboItem).CurrentValues.SetValues(ruleViewModel.Rule);
// Save the differences
ruleViewModel.MainViewModel.dbo.SaveChanges();
如果用户只保存一个规则,一切正常,但如果他们随后尝试保存另一个规则,或者一次保存多个规则,则会收到以下错误,由 ..SetValues(..) 返回行:
Message = "The property 'Id' is part of the object's key information and cannot be modified. "
我从有关此主题的其他问题中看到,EF 有一个功能可以阻止您将同一对象两次写入具有不同 ID 的数据库,因此此错误经常发生在循环中。我尝试使用一些建议,例如添加
viewModel.MainViewModel.dbo.Rules.Add(dboItem);
和
viewModel.MainViewModel.dbo.Entry(dboItem).Property(x => x.Id).IsModified = false;
在SaveChanges() 命令之前,但这并没有解决问题(更不用说更改代码的功能了)。我看到其他一些建议说应该在循环中创建条目,但在这种情况下,条目都是数据库中现有的规则 - 在我看来(可能是错误的)我无法在保存循环中创建它们,因为它们是构建循环的对象 - 对于我找到的每个实体,我想保存更改。
我真的很困惑该怎么做,并且越来越纠结于试图修复错误。现在已经好几天了,我的理智和自尊开始减弱!任何让我朝着正确的方向工作以阻止错误出现并允许我设置数据库值的指针都会非常受欢迎,因为我觉得我已经走到了完全的死胡同!第一次循环,一切正常。
【问题讨论】:
-
您最好在代码中显示实际发生的情况。不可能从描述中完全将其拼凑起来。特别是。上下文的生命周期以及键和历史记录会发生什么。
标签: c# entity-framework mvvm entity-framework-6