我正在使用 self-tracking WCF 客户端-服务器应用程序中的实体。我的 WCF 服务返回各种实体,这些实体可以使用相应的 Update 方法进行更新。
这工作了一段时间,但现在我遇到了问题。为了保持重点,我将把这个讨论限制在一个特定的案例中,简化为最基本的内容。
我的一张表称为 SystemDefinition。它没有外键,但另一个表(Route)有一个外键。因此,它在实体模型中有一个导航属性(称为 Routes)。所有其他列都是标量。该表和相应的实体有一个名为 Id 的主键列,类型为 Guid。该数据库是 SQL Server Compact v3.5。
要重现该问题,我可以:
UpdateSystem() 中的代码很简单(为了清楚起见,删除了非必要代码):
_objectContext.SystemDefinitions.ApplyChanges(system);
_objectContext.SaveChanges();
该实体是在没有 Include() 子句的情况下检索的,这意味着 Routes 集合为空(无论如何,如果 Route 中没有具有 SystemDefinition 外键的行,则仍然会发生错误)。所以我传递给 Update 方法的 SystemDefinition 实体是 图中唯一的实体 .但是我仍然遇到以下异常:
InvalidOperationException: AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
异常由第一个方法调用 (ApplyChanges) 引发。我确定 ObjectContext 是新鲜的,为每个方法调用创建一个新的。
我已经将代码一直调试到它抛出的位置(在 ObjectContext.FixupKey() 中),但代码对我来说意义不大,并且微软的源代码中没有注释来说明导致它的条件实际上意味着什么.
当然,该消息具有误导性?更新中只涉及一个实体。可能会发生什么?
PS。我发现一个论坛帖子建议覆盖实体类上的 GetHashCode() 和 Equals() 方法可能会有所帮助。如果错误是由于 ObjectStateManager 无法确定要更新的实体实际上与上下文中的某些实体相同,那么这将是有道理的。我试过了(使用部分类),但不幸的是它没有帮助。所以现在我迷路了。欢迎大家提出意见。
最佳答案
我怀疑你的 _objectContext
已包含您尝试从中应用更改的实体实例。由于您的实体是从外部客户端接收的,因此它们永远不会与上下文已经知道的那些实例相同(就实例引用而言)。
这对于抛出的异常是有意义的:上下文以两个包含相同键值的不同实例结束。
要解决这个问题,您只需确保始终使用新的上下文。
关于.net - 无法更新自跟踪实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3882352/