Entity Framework中DbSet查询未反映底层数据最新变更的原因是什么
问题原因
Entity Framework 内置了**一级缓存(上下文缓存)**机制:
你首次调用dbcontext.Cart.Find(cartID)查询主键为200的Cart实体时,EF会将返回的实体对象存储在当前ShoppingEntities实例的缓存池中。后续同一个DbContext实例调用Find方法查询相同主键的实体时,EF会优先匹配本地缓存,直接返回已存在的实体,不会主动发起数据库请求拉取最新数据。
你通过存储过程更新的是数据库底层数据,这个操作没有同步到当前EF上下文的缓存中,因此第二次调用Find返回的还是缓存里的旧实体,所以quantity还是9。
可行解决方案
- 方案1:使用无跟踪查询绕过缓存
将第二次查询改为不使用缓存的查询方式,示例代码:
check = dbcontext.Cart.AsNoTracking().FirstOrDefault(c => c.Id == cartID);
AsNoTracking()会告诉EF本次查询的结果不加入缓存,每次都会直接请求数据库拿到最新数据。
- 方案2:手动清除对应实体的缓存
在第二次查询前,先把本地缓存的对应实体分离,后续Find就会重新去数据库查询:
// 移除本地缓存的旧实体 var cachedCart = dbcontext.Cart.Local.FirstOrDefault(c => c.Id == cartID); if (cachedCart != null) { dbcontext.Entry(cachedCart).State = EntityState.Detached; } check = dbcontext.Cart.Find(cartID);
- 方案3:刷新已有实体的最新值
如果你已经持有实体对象,直接调用Reload()方法从数据库拉取最新值覆盖旧属性:
// 存储过程执行后刷新实体 dbcontext.Entry(check).Reload(); // 此时check.quantity已经是数据库最新的10
- 方案4:使用新的DbContext实例查询
如果当前上下文没有其他需要保留的状态,直接新建上下文来查询,新上下文没有旧缓存,返回的就是最新数据:
using (var newDb = new ShoppingEntities()) { check = newDb.Cart.Find(cartID); }
内容的提问来源于stack exchange,提问作者dar25
相关产品推荐
相关产品推荐

