Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 更新自跟踪实体时出现问题_.net_Ado.net Entity Data Model_Self Tracking Entities - Fatal编程技术网

.net 更新自跟踪实体时出现问题

.net 更新自跟踪实体时出现问题,.net,ado.net-entity-data-model,self-tracking-entities,.net,Ado.net Entity Data Model,Self Tracking Entities,我正在WCF客户机-服务器应用程序中使用实体。我的WCF服务返回各种实体,可以使用相应的更新方法更新这些实体 这在一段时间内效果不错,但现在我遇到了问题。为了保持重点,我将把讨论局限于一个具体的案例,简化为最基本的内容 我的一个表叫做SystemDefinition。它没有外键,但另一个表(路由)有一个外键。因此,它在实体模型中只有一个导航属性(称为路由)。所有其他列都是标量。表和相应的实体有一个名为Id的主键列,类型为Guid。数据库是SQL Server Compact v3.5 要重现问题

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

这在一段时间内效果不错,但现在我遇到了问题。为了保持重点,我将把讨论局限于一个具体的案例,简化为最基本的内容

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

要重现问题,我可以:

  • 使用我的WCF服务的GetSystem()方法检索单个SystemDefinition实体
  • 在客户端中,对实体调用MarkAsDeleted()
  • 调用UpdateSystem(),将实体作为参数传递
  • UpdateSystem()中的代码很简单(为了清楚起见,删除了非必要代码):

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

    无效操作例外: AcceptChanges无法继续,因为 对象的键值与 中的另一个对象 ObjectStateManager。确保 在调用之前,键值是唯一的 接受变化

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

    我一直在调试代码,直到它抛出的地方(在ObjectContext.FixupKey()中),但是代码对我来说没有什么意义,并且在Microsoft的源代码中没有任何注释来说明导致它的条件实际上意味着什么

    当然,这个信息是误导性的?更新只涉及一个实体。可能发生了什么


    另外,我发现一篇论坛帖子建议重写实体类上的GetHashCode()和Equals()方法可能会有所帮助。如果错误是由ObjectStateManager无法确定要更新的实体实际上与上下文中的某个实体相同而导致的,那么这将有一定意义。我尝试过(使用分部类),但很不幸,它没有帮助。所以现在我迷路了。欢迎提供任何建议。

    我怀疑您的
    \u objectContext
    已经包含您试图应用更改的实体实例。因为您的实体是从外部客户机接收的,所以它们(在实例引用方面)与上下文已经知道的那些实例永远不会相同

    对于抛出的异常,这是有意义的:上下文以包含相同键值的两个不同实例结束


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

    这是完全正确的。我将单个对象上下文注入到WCF服务构造函数中,认为它是每次调用实例化的。结果是服务实例被重用,因此对象上下文已过时。我重写了服务,改为使用工厂,这就解决了问题。谢谢
    _objectContext.SystemDefinitions.ApplyChanges(system);
    _objectContext.SaveChanges();