尝试重新附加对象时,为什么会出现InvalidOperationException

时间:2012-04-04 17:33:36

标签: c# entity-framework detach

我试图理解为什么我的代码崩溃(我开始工作)时遇到了一些困难。

当您查看原始方法和工作方法时,一行的位置不同

ctx.Inventories.Attach(this);

当原始方法不起作用但第二种方法不起作用时,我很困惑。 任何人都可以提供一些见解吗?

这是我得到的例外。

System.InvalidOperationException:ObjectStateManager中已存在具有相同键的对象。 ObjectStateManager无法使用相同的键跟踪多个对象。

这是我原来的方法

  public void RemoveDependency(int depId)
    {
        bool returnValue = false;

        if (this.Id != 0 && depId > 0)
        {
            using (ApsEntities ctx = new ApsEntities())
            {
                var query2 = from d in ctx.Dependencies
                             where d.Id == depId
                             select d;

                Dependency found = query2.FirstOrDefault();

                if (found != null)
                {
                **ctx.Inventories.Attach(this);**
                    ctx.ObjectStateManager.ChangeObjectState(this, EntityState.Modified);
                    this.Dependencies.Remove(found);

                   ctx.SaveChanges();
                }
            }
        }

        return returnValue;
    }

这是我的工作方法

public void RemoveDependency(int depId)
{
    bool returnValue = false;

    if (this.Id != 0 && depId > 0)
    {
        using (ApsEntities ctx = new ApsEntities())
        {
            **ctx.Inventories.Attach(this);**

            var query2 = from d in ctx.Dependencies
                         where d.Id == depId
                         select d;

            Dependency found = query2.FirstOrDefault();

            if (found != null)
            {
                ctx.ObjectStateManager.ChangeObjectState(this, EntityState.Modified);
                this.Dependencies.Remove(found);

               ctx.SaveChanges();
            }
        }
    }

    return returnValue;
}

1 个答案:

答案 0 :(得分:3)

此行为与跟踪关系的ObjectStateManager有关。

如果Inventory不知道当前的ObjectContext项目(如您的第一个示例所示),那么上下文无法识别InventoryDependency之间的关系。由于Inventory ObjectContext未知InventoryObjectContext的查询会加载它,并且当您将该项添加到Inventory时该项已存在。

在第二个示例中,首先附加ObjectContext,然后执行查询。然后,Dependency会将Inventory对象显式附加到ObjectContext项。

documentation州:

  

ObjectStateManager跟踪查询结果,并提供合并逻辑   多个重叠的查询结果。它还执行内存中的更改   跟踪用户何时插入,删除或修改对象,以及   提供更新的更改集。此更改集由。使用   改变处理器以保持修改。

当{{1}}不知道相关对象时,不会发生此行为。