EF写了个简单的框架,在把查询出来的数据修改回去时,报了ObjectStateManager 中已存在具有同一键的对象这样一个错误,寻寻觅觅终于找到了最终的解决方案。
ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。
说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.InvalidOperationException: ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同
键的多个对象。
网上有资料说是这样先改成未附加状态db.Entry(entity).State = EntityState.Detached,再进行修改。但是我是在基类里面写的方法,传过来的泛型的T,而且我没有把所有的Model都继承自BaseModel,因此T中拿不到主键,也就没办法去数据库中Find这个对象,直接更改更改后的实体对象的状态依然会报错。
所以,这个方法行不通。那只能另想办法了,查找资料之后发现,这是由于查询之后的数据,EF默认帮我们缓存了起来,放在了DbContext上下文中,我们在修改的时候,需要执行操作db.Entry(entity).State = EntityState.Modified; 需要再次的向上下文中附加该实体时候,EF发现该实体已经附加过了,所以会报这个错。所以自然也就有了解决办法。
解决方法,在查询的时候加上asNoTracking() 即可。。。这样,EF就不会缓存查询出来的对象了!
Update方法照样这样写:
public virtual bool Update(T entity) { db.Entry(entity).State = EntityState.Modified; return true; }