Dispose DbContext不处理ObjectContext实体

时间:2012-11-17 16:21:52

标签: asp.net .net entity-framework dispose dbcontext

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

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

确定实体未被处置。如何管理这种情况?我是否必须处置ObjectContext以处置实体,或者有没有办法检查实体是否已附加?

问候。

4 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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);
}

答案 2 :(得分:0)

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

答案 3 :(得分: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
}

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

但如果没有关于代码的更多详细信息,就无法找到确切的原因。