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 语句之前执行。
我有一个瞬态 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 语句之前执行。