我有一些逻辑,需要克隆POCO实体的图形,为此,我为每个T4生成的自跟踪实体创建了部分类,并在每个实现了ICloneable。每个实体都可以克隆自身,并在导航属性中遍历其所有子节点,并在每个子实体上调用Clone(),然后最终返回自己的克隆实例,并添加其克隆子节点。所以这是一个深刻的克隆,工作正常。在克隆树中,所有实体都处于已添加状态,这是有意义的......因为克隆图是所有新实体。
克隆进程在实体上下文中使用服务端,但克隆进程本身没有进行数据访问,克隆是在数据库中新检索的图形上执行的(如果有更好的克隆方法的话)实体图随时通知我......)。
现在,克隆的图表将通过WCF发送到我们的Silverlight 4应用程序并显示在那里。用户可以立即保存或添加/修改此图表中的数据,然后将其保存回服务没有问题,但是,如果他们从图表中删除任何节点,这是一个问题。
当用户单击控件以删除节点时,我通过调用MarkAsDeleted()来更改实体图。这适用于Unchanged图表,但是我的克隆图表中的所有内容都处于Added状态,在WCF服务中保存回数据库后,我收到OptimisicConcurrencyException。
“存储更新,插入或删除语句影响了意外的行数(0)。实体可能已被修改或删除,因为实体已加载。刷新ObjectStateManager条目。”
在我打电话的服务中
context.EntitySetX.ApplyChanges(entityNodeInTree);
context.SaveChanges();
除了这一个场景外,这一切都很好。到目前为止,用户的工作是将克隆的图形保存回数据库,再次检索它(现在将全部保持不变),然后删除他们希望的任何数据,最后再次保存。
我不明白为什么会这样。是不是你不能MarkAsDeleted处于添加状态的东西?这对我来说真的没有意义,因为在使用我们的Silverlight应用程序期间有些项目都被添加然后从图表中删除,这不会导致问题。
有什么想法吗?
由于
答案 0 :(得分:2)
解决!
我遇到的问题是由于在服务器端克隆期间未启用跟踪的新添加实体彼此添加,而是在客户端发生删除,其中跟踪始终开启(由于反序列化转向)追踪跟踪。
关键是在服务器端图形中每个实体的克隆过程中打开跟踪。因此,当我'新'一个实体时,我首先使用StartTracking方法跟踪实体,然后再做其他事情。这样,当我将克隆的子实体添加到克隆的父实体时,它已经处于跟踪模式。
简而言之,在对自我跟踪的实体做任何事情之前,请确保图表中的所有实体都已开启跟踪!