我已经在我的ASP.NET MVC应用程序上工作了几个月了。当我第一次开始使用它时,我使用的是Entity Framework 4.3(代码优先w/Migrations)。在执行此操作时,尝试在MainClient表上进行更新时遇到了一些问题。 MainClient包含客户端的所有基本信息,并且与BPClient表具有1:1关系,该表包含与该客户端有关BP模块许可协议(protocol)的有关该客户端的更多特定信息。两者都可以在选项卡控件中的同一页面上进行编辑。但是,在尝试将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类进行保存时,该对象本身被视为已分离。作为解决此问题的方法,我对this blog post和this SO question中发现的问题应用了类似的解决方案。鉴于在名为
client
的MainClient对象中传递了Edit方法,以下是重新附加对象的代码的样子(我知道是困惑的):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中的什么使使用该代码提交数据库变得如此不稳定?
有人知道为什么会这样吗?
最佳答案
我本人有这个问题。我使用IDbSet类填充数据库表时,发现是当我使虚拟EF5属性执行延迟加载(我的虚拟属性是数据库中其他对象所在的虚拟属性)时。这意味着我收到了该虚拟属性的新主键。好吧,如果我没有与要引用的对象相关联的特定ID,EF 5会尝试建立双向关系。如果您没有明确告诉EF DBContext中要映射到哪个属性,它将为同一对象设置两个外键,这是不允许的。希望这可以帮助。
关于.net - Entity Framework 4.3与5.0更新差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13978816/