Iro*_*n84 7 .net entity-framework entity-framework-4 entity-framework-5
几个月以来,我一直在研究我的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.
Run Code Online (Sandbox Code Playgroud)
我注意到在调试时,对象本身在进入我的Controller类进行保存时被认为是Detached.作为此问题的解决方法,我对此博客文章和此SO问题中的问题应用了类似的解决方案.以下是在以下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()
Run Code Online (Sandbox Code Playgroud)
在所有测试用例中,这都很好用.直到最近.
最近,我升级了我的应用程序以使用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();
Run Code Online (Sandbox Code Playgroud)
现在它完全正常.没有InvalidOperationException.所以这已经解决得很好.
还在困扰我的是试图找出5.0中的变化,这使得我的早期修复工作停止工作并且对我来说都是不可思议的.为什么该代码在4.3中工作正常但在5.0中不正常?什么在5.0中使用该代码提交到数据库如此不稳定?
有人知道为什么会这样吗?
我自己也有这个问题。我使用 IDbSet 类来填充数据库表,我发现当我使属性虚拟 EF5 执行延迟加载时(我的虚拟属性位于数据库中的其他对象中)。这意味着我收到了虚拟财产的新主键。好吧,如果我没有与我想要引用的对象关联的特定 id,EF 5 会尝试建立双向关系。如果您没有明确告诉 EF 在 DBContext 中映射到哪个属性,它会为同一对象设置两个外键,这是不允许的。希望这可以帮助。