Blazor Server 组件之间的一致数据库上下文

Blazor Server consistent database context between components

我想问一下,在组件之间使用数据库上下文的最佳实践是什么? Blazor 服务器、.Net 5、EF 核心 5.0.8

情况简述:
组件a,表头
组件 b,主要
DbContext 注册为 Transient,Header 和 Main 都有自己的上下文。

但是在例如:更改 Main 中的数据后,它不适用于 Header,因此数据变得不一致。

想法:
1,删除 DbContext 注册并为每个数据库调用手动创建一个新的
2,保持当前架构,但添加一个额外的调用来刷新数据(在需要的地方)
3,将 DbContext 注册为 Scoped 并围绕它构建某种队列服务以逐个处理查询(避免并发调用)并通过 EventAggregator 消息 return 结果。

你怎么看,你是怎么处理这种情况的?

首先,永远不要将 dbcontext 注册为瞬态。它会导致内存和连接泄漏,因为谁来处理 dbcontext?如果它被注入,那么预计注入器将负责处理它 - 在这种情况下是 ServiceProvider,但服务提供者不会处理瞬态服务。

您应该使用 IDbContextFactory<TContext> class 并在需要时创建新实例。请记住,DbContext 是短暂的

根据@Liero 的回答,我最初还使用 IDbContextFactory 在每次服务调用数据库时创建一个新的上下文实例 - 但是对于我的应用程序,我需要跨多个组件进行更改跟踪,我做到了不想打破工作单元模式,因为这会导致一些数据库不一致的问题。

正如您在步骤 (3) 中提到的那样 - 我将 DbContext 保持在范围内(AFAIK 这是默认设置),然后我使用 semaphore 来防止线程问题:

 @code {
        static Semaphore semaphore;
        //code ommitted for brevity
        
         protected override async Task OnInitializedAsync()
         {
             try
             {
                //First open global semaphore
                semaphore = Semaphore.OpenExisting("GlobalSemaphore");

                while (!semaphore.WaitOne(TimeSpan.FromTicks(1)))
                {
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }
                //If while loop is exited or skipped, previous service calls are completed.
                ApplicationUsers = await ApplicationUserService.Get();        
             
             }
             finally
             {
                try
                {
                    semaphore.Release();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ex.Message");
                }
            }
        }

这对于我需要跨组件保留更改跟踪的特定用例非常有效。 Here's my full answer from another related question.