Blazor: A second operation started on this context before a previous operation completed

blazor blazor-server-side c# entity-framework entity-framework-core

Question

I'm creating a server side Blazor app. The following code is in the Startup.cs.

services.AddDbContext<MyContext>(o => o.UseSqlServer(Configuration.GetConnectionString("MyContext")), ServiceLifetime.Transient);
services.AddTransient<MyViewModel, MyViewModel>();

And in the ViewModel:

public class MyViewModel : INotifyPropertyChanged
{
    public MyViewModel(MyContext myContext)
    {
        _myContext = myContext;
    }

    public async Task<IEnumerable<Dto>> GetList(string s)
    {
        return await _myContext.Table1.where(....)....ToListAsync();
    }

And in the razor file.

@inject ViewModels.MyViewModel VM
<input id="search" type="text" @bind="search" />
<input id="search" type="button" value="Go" @onclick="SearchChanged" />   
@code {
    string search = "";
    int currentCount = 0;
    async void SearchChanged() {
        currentCount++;
        dtos = GetList(search);
    }
}

However, sometimes the following error occur when clicking the search button?

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.'

1
4
2/13/2020 10:40:13 PM

Accepted Answer

You can try to create a new scope for each request:

public class MyViewModel : INotifyPropertyChanged
{

    protected readonly IServiceScopeFactory _ServiceScopeFactory;

    public MyViewModel(IServiceScopeFactory serviceScopeFactory)
    {
        _ServiceScopeFactory = serviceScopeFactory;
    }

    public async Task<IEnumerable<Dto>> GetList(string s)
    {
        using (var scope = _ServiceScopeFactory.CreateScope())
        {
            var referenceContext = scope.ServiceProvider.GetService<MyContext>();    
            return await _myContext.Table1.where(....)....ToListAsync();
        }
    }

Here Daniel Roth (Blazor Product Manager) talking about Using Entity Framework Core with Blazor

5
10/11/2019 7:37:16 PM

Popular Answer

I resolve the issue however I think I have lost the Unit Of Work because now I have more than one dbContex :

Constructor :

private AppDbContext _db;
protected override void OnInitialized()
{
    _db = new AppDbContext();
     var query = _db.Set<Group>().AsQueryable();
}

and later I dispose it:

public void Dispose()
{
    _db?.Dispose();
}


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow