繁体   English   中英

尝试通过实体框架更新数据库对象时,对象已存在错误

[英]Object already exists error when trying to update database object via Entity Framework

我正在使用以下方法尝试使用实体框架更新对象:

public static void UpdateItem(Item updatedObject) {

  using (var context = new DbContext())
  {
    context.MyObjectsPropertys.Attach(updatedObject);
    context.Entry(updatedObject).State = EntityState.Modified;
    context.SaveChanges();
  }
}

我在附件上收到错误消息:

 An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

如果我尝试将Attach调用更改为Add调用( 具有相同键的对象已经存在objectstatemanager ),则会得到:

Cannot insert duplicate key in object 'database.Table'. The duplicate key value is (AttributeValue). The statement has been terminated.

我发现了很多与此错误有关的问题,但是在我的情况下,没有任何答案可以正常工作:

我也尝试删除“ Attach”语句,并按照Error带有相同键DbContext的多个对象中的建议进行状态更改,但这也不起作用。

对我而言,最令人沮丧的是,这与成功更新解决方案中其他内容的语句序列完全相同。

您必须检查上下文是否已跟踪具有相同键的实体,并修改该实体而不是附加当前实体:

var trackedEntity = context.MyObjectsPropertys.Find(updatedObject.Id);
context.Entry(trackedEntity).CurrentValues.SetValues(updatedObject);
context.Entry(trackedEntity).State = EntityState.Modified;
context.SaveChanges();

您必须检索相同的对象,此后,DataContext对象将跟踪检索到的对象。 添加肯定会产生错误,因为密钥显然存在于字典中。

我认为您可以使用context.ChangeTracker.Entries()检索本地实体,然后查找相同的键(如果存在)

这是我的处理方式:

    public virtual void Update(TEntity entityToUpdate)
    {
        if (_db.Entry(entityToUpdate).State == EntityState.Added)
            return; // just been added leave state as added

        try
        {
            _dbSet.Attach(entityToUpdate);
        }
        catch (InvalidOperationException ex)
        {
            var trackedEntity = _dbSet.Find(GetKeyValues(entityToUpdate));
            if (trackedEntity == null)
                throw;
            if (_db.Entry(trackedEntity).State != EntityState.Unchanged)
                throw;
            _db.Entry(trackedEntity).State = EntityState.Detached;
            _dbSet.Attach(entityToUpdate);
        }
        _db.Entry(entityToUpdate).State = EntityState.Modified;
    }

    public object[] GetKeyValues(TEntity entity)
    {
        var objectContextAdapter = ((IObjectContextAdapter)_db);
        var name = typeof(TEntity).Name;
        var entityKey = objectContextAdapter.ObjectContext.CreateEntityKey(name, entity);
        var result = entityKey.EntityKeyValues.Select(kv => kv.Value).ToArray();
        return result;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM