无法更新自我跟踪实体

时间:2010-10-07 13:55:55

标签: .net ado.net-entity-data-model self-tracking-entities

我在WCF客户端 - 服务器应用程序中使用self-tracking个实体。我的WCF服务返回各种实体,可以使用相应的Update方法更新这些实体。

这种方法运作良好,但现在我遇到了问题。为了保持关注,我将这个讨论局限于一个特定的案例,简化为基本要素。

我的一个表称为SystemDefinition。它没有外键,但另一个表(Route)有一个外键。因此,它在实体模型中具有单个导航属性(称为路径)。所有其他列都是标量。该表和相应的实体有一个名为Id的主键列,类型为Guid。该数据库是SQL Server Compact v3.5。

为了重现这个问题,我可以:

  1. 使用我的WCF服务的GetSystem()方法
  2. 检索单个SystemDefinition实体
  3. 在客户端中,在实体
  4. 上调用MarkAsDeleted()
  5. 调用UpdateSystem(),将实体作为参数传递
  6. UpdateSystem()中的代码很简单(为了清晰起见,删除了非基本代码):

    _objectContext.SystemDefinitions.ApplyChanges(system);
    _objectContext.SaveChanges();
    

    检索实体时没有Include()子句,这意味着Routes集合为空(无论如何,如果Route中没有带有SystemDefinition外键的行,则仍会出现错误)。因此,我传递给Update方法的SystemDefinition实体是图中的唯一实体。然而,我仍然得到以下例外:

      

    InvalidOperationException异常:   AcceptChanges无法继续,因为   对象的键值与之冲突   另一个对象   ObjectStateManager。确保   密钥值在调用之前是唯一的   的AcceptChanges。

    第一个方法调用(ApplyChanges)抛出异常。我确信ObjectContext是新鲜的,为每个方法调用创建一个新的。

    我已经将代码一直调试到它抛出的位置(在ObjectContext.FixupKey()中),但代码对我来说没什么意义,并且Microsoft的源代码中没有注释来指示导致的条件是什么它实际上意味着。

    当然,这条消息具有误导性?更新中只涉及一个实体。可能会发生什么?

    PS。我找到了一个论坛帖子,建议覆盖实体类的GetHashCode()和Equals()方法可能会有所帮助。如果错误是由ObjectStateManager无法确定要更新的实体实际上与上下文中的某个实体相同,则会有一定意义。我尝试了(使用部分类),但不幸的是它没有帮助。所以现在我迷路了。任何建议都会受到欢迎。

1 个答案:

答案 0 :(得分:1)

我怀疑您的_objectContext已经包含您尝试应用更改的实体实例。由于您的实体是从外部客户端接收的,因此它们将永远不会与上下文已经知道的那些实例相同(就实例引用而言)。

抛出异常时这是有意义的:上下文最终会有两个包含相同键值的不同实例。

要解决此问题,您只需确保始终使用新的上下文。