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

API调用后无法获取数据库最新值的问题排查与解决

问题原因

这是EF Core的**一级缓存(DbContext 跟踪缓存)**导致的:
AppA的整个请求生命周期内使用的是同一个UnitOfWork(对应同一个DbContext实例),第一次查询MasterBOFlightBooking时,EF会把查询到的实体存入ChangeTracker缓存。后续即使数据库被AppB修改,再次查询同一主键的实体时,EF会直接返回缓存里的旧实例,不会主动去数据库拉取最新数据。

解决方案

给出几种可行的处理方式,按需选择:

1. 查询时跳过缓存(推荐)

在第二次查询时添加AsNoTracking(),让EF不使用缓存,直接从数据库获取最新数据:

// 重新查询时添加AsNoTracking()
bookingInfo = await _unitOfWork.MasterBOFlightBookingRepository
                               .Where(x => x.TravelmateId == "TF67271" && x.IsPrimaryPsgnr == true)
                               .AsNoTracking()
                               .FirstOrDefaultAsync();

如果希望所有查询都不使用缓存,也可以在Repository的查询逻辑里默认加上AsNoTracking()。

2. 手动刷新实体缓存

如果需要保留实体跟踪,可以在第二次查询前,手动刷新已缓存的实体:

// 先获取缓存中的实体(如果存在)
var cachedEntity = _unitOfWork.MasterBOFlightBookingRepository
                              .Local
                              .FirstOrDefault(x => x.TravelmateId == "TF67271" && x.IsPrimaryPsgnr == true);
if (cachedEntity != null)
{
    // 从数据库刷新该实体
    await _unitOfWork.DbContext.Entry(cachedEntity).ReloadAsync();
}

// 再执行查询,此时会返回刷新后的实体
bookingInfo = await _unitOfWork.MasterBOFlightBookingRepository
                               .Where(x => x.TravelmateId == "TF67271" && x.IsPrimaryPsgnr == true)
                               .FirstOrDefaultAsync();

注:需要确保UnitOfWork暴露了内部的DbContext实例。

3. 清空DbContext的跟踪缓存

如果当前请求中不需要保留其他跟踪实体,可以直接清空ChangeTracker的缓存:

// 清空所有跟踪的实体
_unitOfWork.DbContext.ChangeTracker.Clear();

// 再执行查询
bookingInfo = await _unitOfWork.MasterBOFlightBookingRepository
                               .Where(x => x.TravelmateId == "TF67271" && x.IsPrimaryPsgnr == true)
                               .FirstOrDefaultAsync();

4. 使用新的UnitOfWork实例

如果UnitOfWork是通过依赖注入创建的,可以通过工厂模式获取一个新的实例,确保第二次查询使用全新的DbContext:

// 假设注入了IUnitOfWorkFactory
var newUnitOfWork = _unitOfWorkFactory.Create();
bookingInfo = await newUnitOfWork.MasterBOFlightBookingRepository
                                 .Where(x => x.TravelmateId == "TF67271" && x.IsPrimaryPsgnr == true)
                                 .FirstOrDefaultAsync();

// 使用后记得释放(如果需要)
await newUnitOfWork.DisposeAsync();

内容的提问来源于stack exchange,提问作者Thanh Nguyen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:22:51