EF Core Transient DBContext 获取旧值

EF Core Transient DBContext get old value

我有一个瞬态 EF DB 上下文和一个瞬态服务。

我有一个控制器,其动作使用会话服务更新会话,然后使用会话服务查询更新后的会话。

然而,即使我使用瞬态,当我查询更新后的会话时,会话仍然是旧值而不是更新后的值。有人可以回答为什么吗?

我的预期行为是,如果 DBContext 和 SessionService 是瞬态的,在我更新的会话之后获取应该 return 一个新的更新值而不是旧值。因为 DBContext 应该在更新后被释放。

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    string connectionString = Configuration.GetConnectionString("ASPState");
    services.AddDbContext<ASPStateContext>(options =>
        options.UseSqlServer(connectionString, builder=> {
            builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
        }),ServiceLifetime.Transient);
    services.AddTransient<ISessionService, SessionService>();
    services.AddControllers();
}

SessionService.cs - 使用 DI

private ASPStateContext aspStateContext;
public SessionService(ASPStateContext dbContext)
{
    aspStateContext = dbContext;
}

public async Task<IActionResult> UpdateSession(string id) {
    await this.sessionService.UpdateSession(id);
    var session = this.sessionService.GetSession(id); // return the value before update
}

ASPStateContext.cs

public partial class ASPStateContext : DbContext
{
    public ASPStateContext()
    {
    }

我认为可能对 Transient 范围的工作方式存在误解。每次注入时都会实例化瞬态依赖项。在您的控制器中,瞬态和作用域依赖的行为方式相同。当另一个服务依赖于临时服务时,就会出现差异;该其他服务将接收临时服务的新实例。

因此,您的控制器将对整个请求使用相同的 SessionService(和相同的 EF 上下文)。

要确保 Entity Framework 从数据库中检索最新值,请使用 AsNoTracking 查询扩展 (documentation here)。这将完全绕过EF缓存并查询底层数据库。

另外,请确保在更新会话数据后等待您的 EF 调用以保存更改。否则,您的 SELECT 语句可能会在应用 UPDATE 语句之前执行。