You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编辑后集合导航属性未刷新(重载)的技术问题求助

解决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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 15:45:18