您好,
我有一个运行在postgresql数据库服务器上的EF Core的ASP.NET核心应用程序。我遇到了这个问题:
当我从控制器访问数据库时,一切正常。 但是当我尝试从中间件访问数据库时,会发生异常(在更高的请求负载下):
System.InvalidOperationException: An operation is already in progress.
at Npgsql.NpgsqlConnector.StartUserAction(ConnectorState newState)
at Npgsql.NpgsqlCommand.<ExecuteDbDataReaderInternalAsync>d__4.MoveNext()
...
示例代码:
数据库配置
private void ConfigureDatabase(IServiceCollection services)
{
var connectionString = ConfigObject.Value.DbContextSettings.ConnectionString;
services.AddDbContext<ApplicationDbContext>(opts => opts.UseNpgsql(connectionString));
}
的DbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, Role, Guid>
{
...
public DbSet<SomeItem> SomeItems { get; set; }
...
}
中间件
public async Task Invoke(HttpContext context)
{
var test = await _context.SomeItems.FirstOrDefaultAsync();
}
控制器
public async Task<SomeItem> GetStuff()
{
return await _context.SomeItems.FirstOrDefaultAsync();
}
我的问题是 - 为什么控制器能够提供许多异步并发请求而不是中间件?我怎样才能让它发挥作用?我现在在异步性和ASP.NET解剖学方面有点迷失。
提前谢谢。
答案 0 :(得分:1)
在中间件中使用构造函数注入时,如果依赖关系生存期是作用域的,则会导致captive dependency。您使用了ApplicationDbContext
并且它是作用域的。所以问题可能就是出于这个原因。为避免这种情况,您可以将依赖项作为参数传递给Invoke
方法:
public async Task Invoke(HttpContext context, ApplicationDbContext _context)
{
var test = await _context.SomeItems.FirstOrDefaultAsync();
}
答案 1 :(得分:0)
我不确定你为什么会收到错误,但两种方法都不一样。中间件没有返回类型,控制器也没有“SomeItem”#。此外,只需立即返回Async方法并从任务中删除asnyc等待。
public async Task GetStuff()
{ return await _context.SomeItems.FirstOrDefaultAsync(); }
public Task<SomeItem> GetStuff()
{
return _context.SomeItems.FirstOrDefaultAsync();
}