0

我在 VS 2012 中调试时收到此异常

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

//_dbSet declaration: 

    private readonly IDbSet<T> _dbSet;


//Method parameter

    public virtual void Update(T entity)


//method fragment   



 public virtual void Update(T entity)
    {
        if (Entities == null) return;

        var entry = Entities.Entry(entity);

        switch (entry.State)
        {
            case EntityState.Modified:
                var currentValues = entry.CurrentValues.Clone();
                entry.Reload();
                switch (entry.State)
                {
                    case EntityState.Detached:
                        Entities.Entry(entry).State = EntityState.Modified;
                        break;
                    default:
                        entry.Reload();
                        entry.CurrentValues.SetValues(currentValues);
                        break;
                }
                break;
            case EntityState.Detached:
                _dbSet.Attach(entity); /*Here is the thing*/
                entry.CurrentValues.SetValues(entity);
                break;
        }
        Entities.Commit();
    }

我花了将近一周的时间尝试使用以下模式解决乐观并发问题:DbFactory、工作单元、DI、通用存储库,但没有得到结果。

4

3 回答 3

0

我要感谢所有为我的头疼付出了宝贵时间的人。这是一篇新文章,阐明了我对通用存储库模式中并发更新方法的最终解决方案。这篇文章没有丢失任何东西: Seeking Entity's Key by Attribute Also

这非常有用:RoccoC5


private object GetKeyValue(T entity)
    {
        var key =
            typeof(T).GetProperties().FirstOrDefault(
                p => p.GetCustomAttributes(typeof(KeyAttribute), true).Length != 0);
        return (key != null) ? key.GetValue(entity, null) : null;
    } 

公共虚拟无效更新(T实体){如果(实体==空)返回;

        var key = GetKeyValue(entity);
        var originalEntity = _dbSet.Find(key);
        Entities.Entry(originalEntity).CurrentValues.SetValues(entity);
        Entities.Commit();
   }
于 2013-01-30T21:34:59.193 回答
0

我相信异常消息很清楚:

具有相同键的实体(即映射到同一数据库记录的实体)已加载并附加到目标中DbSet

在这种情况下,您决定做什么完全取决于您:

  • 您可以获取已加载的等效条目并修改附加等效项的值以匹配entity实例(或任何更复杂的);
  • 您可以分离等效的加载条目并附加您的参数entity
  • 你可以跳过它;
于 2013-01-18T15:15:56.617 回答
0

代码闻起来很糟糕;

第一条switch语句使用entry.Stateand 检查实体是处于修改状态还是处于分离状态;然后在修改后的情况下,创建一个新的 switch 语句来检查实体是分离的还是处于其他状态。

该异常没有说明乐观并发。相反,它表明您正在尝试将实体附加到对象上下文,并且上下文中已经存在具有相同键的实体。

于 2013-01-18T15:16:53.357 回答