编辑后集合导航属性未刷新(重载)的技术问题求助
解决EF导航属性刷新后DataGrid不显示新增/删除条目的问题
问题核心是EF的一级缓存机制在起作用:DbContext会缓存已查询过的实体,后续查询默认返回缓存里的旧实例,哪怕数据库数据已经更新。你重置IsLoaded再Load导航属性,本质还是操作缓存中的旧实体,自然看不到新增/删除的条目。
给你三个可行的解决方案:
方案1:使用无跟踪查询(最简单)
让查询绕过一级缓存,每次从数据库拉取最新数据。无跟踪实例需先附加到上下文才能加载导航属性:
count = query.Count(); // 加上AsNoTracking()跳过一级缓存 var resumes0 = query.AsNoTracking() .Skip(args.Skip.Value) .Take(args.Top.Value) .ToList<Resume>(); resumes0.ForEach(r => { context.Attach(r); // 无跟踪实例必须先附加到上下文才能加载导航属性 context.Entry(r).Collection(r => r.ResumeSkills).Load(); }); resumes = resumes0;
方案2:清理本地缓存后再查询
如果需要保留实体跟踪,先分离上下文本地缓存中的旧Resume实例,后续查询就会从数据库取新数据:
// 分离本地缓存中所有已跟踪的Resume实例 foreach (var resume in context.Resumes.Local.ToList()) { context.Entry(resume).State = EntityState.Detached; } count = query.Count(); var resumes0 = query.Skip(args.Skip.Value) .Take(args.Top.Value) .ToList<Resume>(); resumes0.ForEach(r => { context.Entry(r).Collection(r => r.ResumeSkills).Load(); }); resumes = resumes0;
方案3:使用全新的DbContext实例
DbContext的缓存是实例级的,直接创建新上下文查询,能保证拿到最新数据,同时建议用Include替代手动循环Load导航属性,代码更简洁:
// 用新的上下文实例查询 using (var newContext = new YourDbContext()) { count = newContext.Resumes.Count(query.Expression); // 复用原查询条件 var resumes0 = newContext.Resumes .Skip(args.Skip.Value) .Take(args.Top.Value) .Include(r => r.ResumeSkills) .ToList(); resumes = resumes0; }
内容的提问来源于stack exchange,提问作者mz1378
相关产品推荐
相关产品推荐

