Search code examples
c#.net-6.0background-service

Error: Cannot insert explicit value for identity column in table in BackgroundServices


I have a method in BackgroundServices that successfully retrieves data from an API. But when saving the response data to dbContext, I get the error: Cannot insert explicit value for identity column in table 'Orders' when IDENTITY_INSERT is set to OFF.

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

When I test the API in Postman and BackgroundServices is not used, SaveChangesAsync() works. Can someone please assist?

    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();
        }

    }   
}

Solution

  • I fixed the error. It was in how I was using ScopeServices. I refactored the method by removing using(var scope = Services.CreateScope()) statements and instantiated them like so at the top of the method using ScopeFactory. The OrderScopeService is used in another part of the method. But if you need to add multiple scope services this is an example.

                using var scope = _serviceScopeFactory.CreateScope();
                var OrderScopeService = scope.ServiceProvider.GetService<IOrder>();
                var DbContextScopeService = scope.ServiceProvider.GetService<MyDbContext>();
    

    I did not need to add this annotation to the entity key

    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    

    Final Edit

                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();