几个月来,我一直在研究我的 ASP.NET MVC 应用程序。当我第一次开始研究它时,我使用的是 Entity Framework 4.3 (Code-First w/Migrations)。当我这样做时,我在尝试对 MainClient 表进行更新时遇到了一些问题。MainClient 包含客户的所有基本信息,并与 BPClient 表具有 1:1 的关系,该表包含有关该客户的更多具体信息,与他们的 BP 模块许可协议有关。两者都可以在选项卡控件的同一页面上进行编辑。但是,在尝试将 MainClient 对象的 EntityState 更改为 EntityState.Modified 时,我不断收到以下异常:
System.InvalidOperationException : An object with the same key already exists
in the ObjectStateManager. The ObjectStateManager cannot track multiple objects
with the same key.
我在调试时注意到,当对象进入我的 Controller 类进行保存时,它本身被认为是分离的。作为这个问题的解决方法,我对这篇博文和这个 SO question中发现的问题应用了类似的解决方案。考虑到在名为 MainClient 的对象中传递了 Edit 方法,下面是重新附加对象的代码之后的样子(我知道很乱)client
:
var newClientObject = new MainClient { ClientID = client.ClientID };
Db.MainClients.Attach(newClientObject);
Db.Entry(newClientObject).CurrentValues.SetValues(client);
var bpClient = new BPClient { ClientID = client.ClientID, BaseClient = newClientObject };
if (client.BPClient != null)
{
Db.BostonpostClients.Attach(bpClient);
Db.Entry(bpClient).CurrentValues.SetValues(client.BPClient);
}
Db.SaveChanges()
这在所有测试用例中都工作得很好而且很花哨。直到最近。
最近,我升级了我的应用程序以使用 Entity Framework 5(仍然使用 Code-First)。但是,当我再次测试 MainClient 编辑页面时,我发现了一些相当不稳定的行为。某些字段在编辑时可以毫无问题地保存。其他人永远不会致力于数据库。还有一些会很好,但前提是它们是被编辑对象的唯一部分。我调试了 Controller 类中的 DbContext ,发现,相当烦人的是,不仅页面上所做的更改被发送到 Controller 类,而且 ObjectStateManager 中同时包含 MainClient 和 BPClient 对象它也与页面上所做的更改一起!顺便提一下,我在调试它时没有收到一个错误,即使在 SaveChanges() 之后也没有。
我决定尝试将代码恢复到原来的样子,也就是说这样做的逻辑方式:
Db.Entry<BPClient>(client.BPClient).State = EntityState.Modified;
Db.Entry<MainClient>(client).State = EntityState.Modified;
Db.SaveChanges();
现在它工作得很好。没有 InvalidOperationException。所以这已经很好地解决了。
仍然困扰着我的是试图弄清楚 5.0 中的哪些变化使我之前的修复停止工作并且对我来说很不稳定。为什么该代码在 4.3 中可以正常工作,但在 5.0 中却不行?是什么在 5.0 中使使用该代码提交到数据库如此不稳定?
有谁知道为什么会发生这种情况?