Martin Zaloga
Martin Zaloga

Reputation: 125

System.InvalidOperationException: A second operation started on this context before a previous operation completed in Blazor and EFCore

I have method like the DeleteSettingAbout() after in text, where I am still getting error: "System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.".

Code of the method is:

public async Task DeleteSettingAbout(int Id)
    {
        SettingAbout setting = await _context.SettingsAbout.FirstOrDefaultAsync(o => o.Id == Id);

        if (setting != null)
        {
            _context.SettingsAbout.Remove(setting);

            await _context.SaveChangesAsync();
        }
    }

In sartup.cs I set DBContext and DBRepository as Transient:

    services.AddDbContext<AppDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("AppDBConnection")),
            ServiceLifetime.Transient);
        services.AddTransient<IAppDbRepository, SQLAppDbRepository>();

But I am still getting this error.

How to solve this behavior? Thanks for answers.

UPDATE 2021-01-06

I tried the approach with creating the "DbContextFactory" and it solved my problem. I got inspiration from sample app https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/blazor/common/samples/3.x/BlazorServerEFCoreSample (mentioned here: https://learn.microsoft.com/en-us/aspnet/core/blazor/blazor-server-ef-core?view=aspnetcore-3.1#sample-app-3x).

Now I have in my startup.cs this:

    // new way suitable for Blazor - register factory and configure the options (new instance for each method call)
        services.AddDbContextFactory<AppDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("AppDBConnection")));
        services.AddScoped<IAppDbRepository, SQLAppDbRepository>();

Upvotes: 0

Views: 1379

Answers (1)

Martin Zaloga
Martin Zaloga

Reputation: 125

I tried the approach with creating the "DbContextFactory" (mentioned by Stephen Cleary) and it solved my problem. I got inspiration from sample app https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/blazor/common/samples/3.x/BlazorServerEFCoreSample (mentioned here: https://learn.microsoft.com/en-us/aspnet/core/blazor/blazor-server-ef-core?view=aspnetcore-3.1#sample-app-3x).

Now I have in my startup.cs this:

// new way suitable for Blazor - register factory and configure the options (new instance for each method call)
    services.AddDbContextFactory<AppDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("AppDBConnection")));
    services.AddScoped<IAppDbRepository, SQLAppDbRepository>();

Note: I needed to solve the problem in EF/Blazor = v3.1 (because my web-hosting does not support v5 for now)

Thank you all for answers!

Upvotes: 0

Related Questions