错误:无法在BackgroundServices的表中为标识列插入显式值



我在BackgroundServices中有一个方法可以成功地从API检索数据。但是,当将响应数据保存到dbContext时,我得到了错误:当identity_insert设置为OFF时,无法在表"Orders"中为标识列插入显式值。

//In Program.cs    
builder.Services.AddHostedService<ConsumedScopeServiceHostedService>();

当我在Postman中测试API并且没有使用BackgroundServices时,SaveChangesAsync((起作用。有人能帮忙吗?

public class ConsumedScopeServiceHostedService : BackgroundService
{
public ConsumedScopeServiceHostedService
(
IServiceProvider services
)
{
Services = services;
}
public IServiceProvider Services { get; }
private readonly PeriodicTimer _importOrdersTimer = new PeriodicTimer(TimeSpan.FromMinutes(2));
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (await _importOrdersTimer.WaitForNextTickAsync(stoppingToken) && !stoppingToken.IsCancellationRequested)
{
await DoWorkAsync();         
}
}

private async Task DoWorkAsync()
{
using (var scope = Services.CreateScope())
{
var scopedDbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>();
foreach (var item in newOrders)
{
scopedDbContext.Add(item);
}
scopedDbContext.SaveChanges();
}
}   
}

根据错误,我认为您正在向OrderId(PK字段(传递一个值。如果您已经启用了标识,并且正在从DB中自动递增值,则不能为"插入"场景传入ID字段的值。

如果确实需要从代码传递Id,则必须使用以下命令在数据库中启用IDENTITY_INSERTSET IDENTITY_INSERT TableName ON

编辑

[DatabaseGenerated(DatabaseGeneratedOption.None)]添加到主键列中。然后尝试添加事务范围,也如下

using var transaction = scopedDbContext.Database.BeginTransaction();
scopedDbContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Orders ON;");
foreach (var item in newOrders) 
{ 
scopedDbContext.Add(item); 
} 
scopedDbContext.SaveChanges(); 
scopedDbContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Orders OFF");
transaction.Commit();
我修复了这个错误。这就是我使用ScopeServices的方式。我通过删除using(var-scope=Services.CreateScope(((语句重构了该方法,并在方法的顶部使用ScopeFactory对它们进行了实例化。OrderScopeService用于该方法的另一部分。但是,如果您需要添加多个作用域服务,这就是一个示例。
using var scope = _serviceScopeFactory.CreateScope();
var OrderScopeService = scope.ServiceProvider.GetService<IOrder>();
var DbContextScopeService = scope.ServiceProvider.GetService<MyDbContext>();

我不需要将此注释添加到实体密钥

[DatabaseGenerated(DatabaseGeneratedOption.None)]

最终编辑

using var scope = _serviceScopeFactory.CreateScope();
var OrderScopeService = scope.ServiceProvider.GetService<IOrder>();
var DbContextScopeService = scope.ServiceProvider.GetService<MyDbContext>();
foreach (var item in newOrders)
{
DbContextScopeService.Add(item);
}
DbContextScopeService.SaveChanges();

最新更新