EF Core 3.1手动修改数据库后调用LoadAsync无法获取更新值如何解决
问题原因
EF Core 默认启用实体跟踪机制,你的_SIMContext是窗体生命周期内的单例实例,首次加载Departments数据后,所有已查询到的实体都会被上下文缓存并持续跟踪。后续再次调用LoadAsync时,EF Core 默认不会覆盖已跟踪实体的现有属性值,仅会将数据库中新增/删除的记录同步到本地缓存,因此修改后的现有记录值无法更新到本地。
你之前尝试的方案未生效的原因:ResetBindings仅通知绑定控件刷新数据源,而数据源本身仍是上下文缓存的旧值;手动修改单个实体状态为Modified也不会主动从数据库拉取最新值,因此无效。
解决方案
提供两种可直接落地的方案,按需选择:
方案1:清除本地跟踪缓存后重新加载(适合需要后续用当前上下文做CRUD的场景)
每次加载数据前先清空当前上下文跟踪的Department实体缓存,再重新拉取最新数据,修改后的LoadDataAsync代码如下:
private async Task LoadDataAsync() { // 清除所有已跟踪的Department实体,解除缓存关联 foreach (var entry in _SIMContext.ChangeTracker.Entries<Department>()) { entry.State = EntityState.Detached; } _SIMContext.Departments.Local.Clear(); // 重新从数据库拉取最新全量数据 await _SIMContext.Departments.LoadAsync().ContinueWith(loadTask => { dataBindingSource.DataSource = _SIMContext.Departments.Local.ToBindingList(); }, TaskScheduler.FromCurrentSynchronizationContext()); }
方案2:使用无跟踪查询直接赋值(适合仅做数据展示、CRUD单独处理的场景)
直接用AsNoTracking取消跟踪查询,拿到最新数据后直接赋值给绑定源,代码更简洁高效:
private async Task LoadDataAsync() { // 无跟踪查询直接拉取最新全量数据 var latestDepartments = await _SIMContext.Departments.AsNoTracking().ToListAsync(); // 直接赋值给绑定源,无需依赖上下文本地缓存 dataBindingSource.DataSource = new BindingList<Department>(latestDepartments); }
内容的提问来源于stack exchange,提问作者M.Bouabdallah
相关产品推荐
相关产品推荐

