3

我正在使用 EF 5.0 创建一个网络,但在处理我的上下文时遇到了一些问题。我使用上下文的所有时间都在使用语句中,因此应该自动处理上下文,但是在特定时刻,当我尝试将实体附加到上下文时,会出现下一个错误:

ObjectStateManager 中已存在具有相同键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。

看来该实体没有被处置。如何处理这种情况?我是否必须处置 ObjectContext 才能处置实体,或者有什么方法可以检查实体是否已附加?

问候。

4

4 回答 4

1

一种方法是在附加之前分离现有对象。我面前没有 VS,所以如果代码不完全正确,我深表歉意。

var existingObject = dbContext.Users.Local
  .FirstOrDefault(x => x.id = newObject.id);

if (existingObject != null)
{
  // remove object from local cache
  dbContext.Entry(existingObject).State = EntityState.Detached;
}

dbContext.Users.Attach(newObject);

如果这不能解决问题,您将不得不采用分离对象的旧方法。

  // remove object from local cache
  ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
  objectContext.Detach(existingObject);
于 2012-11-17T19:06:21.057 回答
0

Dispose并不意味着“恢复出厂设置”。这是一种清理非托管资源(如数据库连接等)的方法。

于 2012-11-17T22:50:51.493 回答
0

这个问题与是否处理上下文无关。它甚至与在某个地方拥有多个上下文无关。如果这是问题所在,您将得到“一个实体对象不能被多个 IEntityChangeTracker 实例引用”异常,这与您的异常完全不同。

您可以仅使用一个上下文非常轻松地模拟您的异常:

using (var ctx = new MyContext())
{
    var customer1 = new Customer { Id = 1 };
    var customer2 = new Customer { Id = 1 }; // a second object with the same key

    ctx.Customer.Attach(customer1);
    ctx.Customer.Attach(customer2); // your exception will occur here
}

导致此异常的问题通常更隐蔽,特别是如果您记住附加或设置状态(例如 to Modified)也会在您附加的实体的对象图中附加所有相关实体。如果在此图中是两个具有相同键的对象,您也会得到异常,尽管您没有明确附加这些相关实体。

但是,如果没有有关您的代码的更多详细信息,就不可能找到确切的原因。

于 2012-11-17T23:15:09.887 回答
0

如果你这样做:

User u;
using (Entities ent = new Entities())
{
    u = ent.Users.Single(a => a.ID == 123);
}
using (Entities ent2 = new Entities())
{
    //loading the same user
    User user2 = ent2.Users.Single(a => a.ID == 123);

    //trying to attach the same object with the same key
    ent2.Attach(u);
}

那么你会得到这个错误(我没有测试过这段代码)。

编辑:解决方案之一是更改对象的状态:

ent2.Attach(u);
ent2.ObjectStateManager.ChangeObjectState(u, EntityState.Modified);

另一种解决方案是检查实体是否已附加:

ObjectStateEntry state = null;
if(!ent2.ObjectStateManager.TryGetObjectStateEntry(((IEntityWithKey)u).EntityKey, out state))
{
    ent2.Attach(u);
}
于 2012-11-17T17:45:35.683 回答