我在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,通用存储库,没有得到结果。
答案 0 :(得分:0)
我相信异常消息足够清楚:
具有相同密钥的实体(即映射到同一数据库记录的实体)已加载并附加到目标DbSet
中。
在这种情况下,您决定做什么完全取决于您:
entity
实例(或更复杂的内容); entity
代替答案 1 :(得分:0)
代码闻起来很糟糕;
第一个switch
语句使用entry.State
并检查实体是处于修改状态还是处于分离状态;然后在修改的情况下,创建一个新的switch语句来检查实体是分离还是处于其他状态。
该异常说明了乐观并发性;相反,它声明您正在尝试将实体附加到对象上下文,并且上下文中已存在具有相同键的实体。
答案 2 :(得分:0)
我要感谢所有人将一些宝贵的时间献给了我的头。 这是一篇新帖子,它清除了Generic Repository模式中并发Update方法的最终解决方案。由于这篇文章,没有任何东西丢失: Seeking Entity's Key by Attribute Along
这非常有用: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;
}
public virtual void Update(T entity) { if(Entities == null)return;
var key = GetKeyValue(entity);
var originalEntity = _dbSet.Find(key);
Entities.Entry(originalEntity).CurrentValues.SetValues(entity);
Entities.Commit();
}