Responsive UI design causing problems for Entity Framework in Blazor application

blazor blazor-server-side entity-framework entity-framework-core

Question

I am familiar with writing highly responsive ASP.NET MVC applications where we load the initial page data, and then fire off multiple AJAX calls to load "secondary" data for the page. So behinds the scenes, these AJAX requests all hit the web server(s) about the same time and pull data from our SQL DB.

I envisage doing something very similar with a Blazor application. So, we'd load the page with some data and then have multiple components then display on the page with additional data; the loading of these components could be initialized by a user action, or by some other event(s) on the page.

And that's where I see a problem: the event handlers all react very nicely to events fired by the various components on the razor page, and they all then hit our DataService (injected into the page) which then results in lots of threads hitting our Entity Framework's Context.

And that's not allowed - only one thread may call the context at any one time.

To get around this, I can lock the Context using a SemaphoreSlip(1,1) to ensure that only one thread gets access at any one time, but that seems a bit of a bottle neck to me. Surely locking the Context is not something that Microsoft would be expecting us to do....??

What am I missing here?

I'm using Blazor-Server, .NET Core 3.1/EF Core 3.1. In my App's startup, I'm setting up the EF Context and the Service for DI:

services.AddDbContext<MyContext>();
services.AddScoped<MyService>();

The Context is injected into the constructor of the Service (as per Microsoft's Blazor examples), and the Service is injected into the Page.

1
1
11/4/2019 6:49:21 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





Related

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