命令已在进行中
A Command Is Already In Progress
我正在尝试 运行 我正在开发的网络应用程序的后台工作者。我正在使用 Npgsql 作为我的 EF Core 提供程序。
为澄清起见,我在 DbContext
中注入了一个 Transient 生命周期,并允许在我的连接字符串中使用 Pooling,但是,每当我尝试对其进行测试时,我都会收到以下错误:
Npgsql.NpgsqlOperationInProgressException: A command is already in progress: [My Query Here]
我的 Program
Class 设置如下:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
// Get the configuration
IConfiguration config = hostContext.Configuration;
// DbContext
services.AddDbContext<MyDbContext>(options => options.UseNpgsql(config.GetConnectionString("PostgreSQLString")), ServiceLifetime.Transient);
services.AddHostedService<Worker>();
services.AddScoped<IDTOService, BackgroundDTOService>();
});
}
然后导致我的 Worker
class
public class Worker : BackgroundService
{
private Logger logger;
public Worker(IServiceProvider services, IConfiguration configuration)
{
this.Services = services;
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionsBuilder.UseNpgsql(configuration.GetConnectionString("PostgreSQLString"));
var context = new StatPeekContext(optionsBuilder.Options);
this.logger = new Logger(new LogWriter(context));
}
public IServiceProvider Services { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
this.logger.LogInformation("ExecuteAsync in Worker Service is running.");
await this.DoWork(stoppingToken);
}
private async Task DoWork(CancellationToken stoppingToken)
{
using (var scope = Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
var dtoService = scope.ServiceProvider.GetRequiredService<IDTOService>();
await dtoService.ProcessJSON(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
this.logger.LogInformation("Worker service is stopping.");
await Task.CompletedTask;
}
}
这导致了我的 BackGroundDTOService
public class BackgroundDTOService : IDTOService
{
private int executionCount = 0;
private Logger logger;
private MyDbContext context;
private DbContextOptionsBuilder<MyDbContext> optionsBuilder;
public BackgroundDTOService(IConfiguration configuration, MyDbContext context)
{
this.optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
this.optionsBuilder.UseNpgsql(configuration.GetConnectionString("PostgreSQLString"));
this.logger = new Logger(new LogWriter(new MyDbContext(this.optionsBuilder.Options)));
this.context = context;
}
public async Task ProcessJSON(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
this.executionCount++;
this.logger.LogInformation($"DTO Service is working. Count: {this.executionCount}");
this.ProcessTeams();
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
}
}
public void ProcessTeams()
{
// Add Any Franchises that don't exist
var franchiseDumps = this.context.RequestDumps.Where(rd => rd.Processed == false && rd.DumpType == "leagueteams");
foreach (RequestDump teamDump in franchiseDumps)
{
var league = this.context.Leagues.Include(l => l.Franchises).FirstOrDefault(l => l.Id == teamDump.LeagueID);
var teams = Jeeves.GetJSONFromKey<List<DTOTeam>>(teamDump.JsonDump, "leagueTeamInfoList");
foreach (DTOTeam team in teams)
{
this.UpdateFranchise(team, league);
}
this.logger.LogInformation($"DTO Service Processed League Teams on count {this.executionCount}");
}
this.context.SaveChanges();
}
当它试图获取 league
时,错误似乎是在捕获 franchiseDumps
之后立即发生的
您可以尝试具体化查询:
var franchiseDumps = this.context.RequestDumps.Where(rd => rd.Processed == false && rd.DumpType == "leagueteams").ToList();
我遇到了同样的问题,我意识到 PostgreSQL
与 MSSQL
相比不支持 Multiple Active Result Sets
(MARS)。
我用外键获取对象的另一种方法:
IEnumerable<Expense> objList = _db.Expenses;
foreach (var obj in objList.ToList())
{
obj.ExpenseCategory = _db.ExpenseCategories.FirstOrDefault(u => u.Id == obj.ExpenseCategoryId);
}
我正在尝试 运行 我正在开发的网络应用程序的后台工作者。我正在使用 Npgsql 作为我的 EF Core 提供程序。
为澄清起见,我在 DbContext
中注入了一个 Transient 生命周期,并允许在我的连接字符串中使用 Pooling,但是,每当我尝试对其进行测试时,我都会收到以下错误:
Npgsql.NpgsqlOperationInProgressException: A command is already in progress: [My Query Here]
我的 Program
Class 设置如下:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
// Get the configuration
IConfiguration config = hostContext.Configuration;
// DbContext
services.AddDbContext<MyDbContext>(options => options.UseNpgsql(config.GetConnectionString("PostgreSQLString")), ServiceLifetime.Transient);
services.AddHostedService<Worker>();
services.AddScoped<IDTOService, BackgroundDTOService>();
});
}
然后导致我的 Worker
class
public class Worker : BackgroundService
{
private Logger logger;
public Worker(IServiceProvider services, IConfiguration configuration)
{
this.Services = services;
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionsBuilder.UseNpgsql(configuration.GetConnectionString("PostgreSQLString"));
var context = new StatPeekContext(optionsBuilder.Options);
this.logger = new Logger(new LogWriter(context));
}
public IServiceProvider Services { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
this.logger.LogInformation("ExecuteAsync in Worker Service is running.");
await this.DoWork(stoppingToken);
}
private async Task DoWork(CancellationToken stoppingToken)
{
using (var scope = Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
var dtoService = scope.ServiceProvider.GetRequiredService<IDTOService>();
await dtoService.ProcessJSON(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
this.logger.LogInformation("Worker service is stopping.");
await Task.CompletedTask;
}
}
这导致了我的 BackGroundDTOService
public class BackgroundDTOService : IDTOService
{
private int executionCount = 0;
private Logger logger;
private MyDbContext context;
private DbContextOptionsBuilder<MyDbContext> optionsBuilder;
public BackgroundDTOService(IConfiguration configuration, MyDbContext context)
{
this.optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
this.optionsBuilder.UseNpgsql(configuration.GetConnectionString("PostgreSQLString"));
this.logger = new Logger(new LogWriter(new MyDbContext(this.optionsBuilder.Options)));
this.context = context;
}
public async Task ProcessJSON(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
this.executionCount++;
this.logger.LogInformation($"DTO Service is working. Count: {this.executionCount}");
this.ProcessTeams();
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
}
}
public void ProcessTeams()
{
// Add Any Franchises that don't exist
var franchiseDumps = this.context.RequestDumps.Where(rd => rd.Processed == false && rd.DumpType == "leagueteams");
foreach (RequestDump teamDump in franchiseDumps)
{
var league = this.context.Leagues.Include(l => l.Franchises).FirstOrDefault(l => l.Id == teamDump.LeagueID);
var teams = Jeeves.GetJSONFromKey<List<DTOTeam>>(teamDump.JsonDump, "leagueTeamInfoList");
foreach (DTOTeam team in teams)
{
this.UpdateFranchise(team, league);
}
this.logger.LogInformation($"DTO Service Processed League Teams on count {this.executionCount}");
}
this.context.SaveChanges();
}
当它试图获取 league
franchiseDumps
之后立即发生的
您可以尝试具体化查询:
var franchiseDumps = this.context.RequestDumps.Where(rd => rd.Processed == false && rd.DumpType == "leagueteams").ToList();
我遇到了同样的问题,我意识到 PostgreSQL
与 MSSQL
相比不支持 Multiple Active Result Sets
(MARS)。
我用外键获取对象的另一种方法:
IEnumerable<Expense> objList = _db.Expenses;
foreach (var obj in objList.ToList())
{
obj.ExpenseCategory = _db.ExpenseCategories.FirstOrDefault(u => u.Id == obj.ExpenseCategoryId);
}