Blazor Server and the Entity Framework. How to avoid multiple conflicting calls to the DB

2

Summary

In my Razor page, a single user action fires off two events. These events result in calls to the EF which result in the error:

System.InvalidOperationException HResult=0x80131509 Message=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.

Setup Rather than have one huge DBContext, I have multiple contexts, each focused on a small area of functionality in the DB. So, let's imagine that here I'm dealing with functionality for working with People.

I therefore have a PeopleContext, and a PeopleService. In my startup, these are registered as:

services.AddDbContext<PeopleContext>();
services.AddScoped<PeopleService>();

And the Context is Dependency Injected into the Service:

public class PeopleService
{
    public PeopleService(PeopleContext context)
    {
        this.Context = context;
    }

    private PeopleContext Context { get; }

Actions

So picture a page that has a grid on the left hand side showing a summary of each person, and an area on the right hand side where we show the details of the selected person.

When someone clicks a row of a grid, we make a call to the Service to load the full details of that person and display that data in the right hand side.

We also have an [Edit] button on the grid. When someone clicks that, it opens up a modal window. That window makes a call the the SAME method on the SAME Service (therefore using the SAME Context) to load the full details so that we can edit the person.

So, my problem is of course that when someone clicks the [Edit] button in the Grid, they're also selecting the current row and so that method gets called twice at almost the same time, resulting in the above conflict.

Solution

I don't think that I want to intoduce the concept of locking because that can lead to performance issues. I also don't want to duplicate the method in a different Service because I want to keep my code DRY. I'm not sure it makes great sense to not fire the SELECT ROW event when someone clicks the button on the row. I also can't be the first person to come across this, so there must be an established "best practice" for this sort of behaviour - hence this post to hopefully discover what that is.


Using: Blazor Server, .NET 3.1

entity-framework
entity-framework-core
blazor-server-side
asked on Stack Overflow Oct 31, 2019 by DrGriff

1 Answer

1

Final solution was:

Razor Page

@inherits OwningComponentBase<Data.MyService>

Startup

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

For more details, see: Using Entity Framework Core with Blazor #10448

answered on Stack Overflow Nov 13, 2019 by DrGriff

User contributions licensed under CC BY-SA 3.0