Handle DbContext and IDbContextFactory<T> lifetime in Blazor InteractiveServer
Hi, I have some trouble getting EfCore to run properly with Blazor components and pages. I scaffolded a project using the Identity UI template and implemented business logic. I wanted to deploy a first version on production but I'm stuck with flaky instances of the DbContext.
For example, the autogenerated
Components/Account/Pages/Manage/Index.razor
Components/Account/Pages/Manage/Index.razor
page contains the following initialization method:
An unhandled exception has occurred while executing the request. System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently 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. at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection() at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync() at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken) at XXXXXXXXXXXXX.Components.Account.IdentityUserAccessor.GetRequiredUserAsync(HttpContext context) in C:\XXXXXXXXXXXXX\Components\Account\IdentityUserAccessor.cs:line 12 at XXXXXXXXXXXXX.Components.Account.Pages.Manage.Index.OnInitializedAsync() in C:\XXXXXXXXXXXXX\Components\Account\Pages\Manage\Index.razor:line 63
An unhandled exception has occurred while executing the request. System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently 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. at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection() at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync() at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken) at XXXXXXXXXXXXX.Components.Account.IdentityUserAccessor.GetRequiredUserAsync(HttpContext context) in C:\XXXXXXXXXXXXX\Components\Account\IdentityUserAccessor.cs:line 12 at XXXXXXXXXXXXX.Components.Account.Pages.Manage.Index.OnInitializedAsync() in C:\XXXXXXXXXXXXX\Components\Account\Pages\Manage\Index.razor:line 63
internal sealed class IdentityUserAccessor( UserManager<ApplicationUser> userManager, IdentityRedirectManager redirectManager){ public async Task<ApplicationUser> GetRequiredUserAsync(HttpContext context) { var user = await userManager.GetUserAsync(context.User); if (user is null) { redirectManager.RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.", context); } return user; }}
internal sealed class IdentityUserAccessor( UserManager<ApplicationUser> userManager, IdentityRedirectManager redirectManager){ public async Task<ApplicationUser> GetRequiredUserAsync(HttpContext context) { var user = await userManager.GetUserAsync(context.User); if (user is null) { redirectManager.RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.", context); } return user; }}
Why is this happening? What am I doing wrong? Thanks for your help in advance!