C# 如何将DbContextPool与Singleton一起使用?

C# 如何将DbContextPool与Singleton一起使用?,c#,dependency-injection,.net-core,entity-framework-core,C#,Dependency Injection,.net Core,Entity Framework Core,在我的应用程序中,我使用NMS和ActiveMQ进行集成。 我有一些侦听器是单例的,它们侦听一些消息队列。 在收到消息后,侦听器应处理该消息并将其记录到数据库中。 我的DbContext是使用DbContextPool选项配置的: services.AddEntityFrameworkSqlServer(); services.AddDbContextPool<MyContext>((serviceProvider, options) =>

在我的应用程序中,我使用NMS和ActiveMQ进行集成。 我有一些侦听器是单例的,它们侦听一些消息队列。 在收到消息后,侦听器应处理该消息并将其记录到数据库中。 我的
DbContext
是使用
DbContextPool
选项配置的:

        services.AddEntityFrameworkSqlServer();
        services.AddDbContextPool<MyContext>((serviceProvider, options) =>
        {
            options.UseSqlServer(connectionString);
            options.UseInternalServiceProvider(serviceProvider);
        });
如何在处理完一条消息后获取池中的一个上下文并释放它?还有其他推荐的方法吗

提前感谢。

根据文档:

从单例解析作用域服务是危险的。在处理后续请求时,可能会导致服务的状态不正确

默认情况下,
AddDbContext
AddDbContextPool
DbContext
注册为
Scoped
服务。您正在
ActiveMqListener
类中使用已注册为
Singleton
服务的
DbContext
。这就是问题所在

解决方案是:
Startup.ConfigureServices
方法中将您的
ActiveMqListener
注册到ASP.NET核心DI作为
ScopedService

注意:如果您必须将
ActiveMqListener
作为
Singleton
使用,请将您的
DbConext
也注册为
Singleton
,如下所示:

services.AddDbContext<MyContext>((serviceProvider, options) =>
        {
            options.UseSqlServer(connectionString);
            options.UseInternalServiceProvider(serviceProvider);
        }, ServiceLifetime.Singleton); // <-- Here it is
services.AddDbContext((serviceProvider,options)=>
{
使用SQLServer(connectionString);
选项。使用InternalServiceProvider(serviceProvider);

},ServiceLifetime.Singleton);//您的
ActiveMqListener
服务注册代码在
Startup.ConfigureServices
方法中的哪里?您好@TanvirArjel,谢谢您的回答。我得到了那个部分,问题是我的
ActiveMqListener
必须是一个单例,因为他总是在我的服务器上运行,他没有绑定到请求(就像作用域服务一样)。因此,我无法确定其范围。有没有关于如何从ContextPool动态获取DbContext的想法?@JoãoMenighin好的!使用
AddDbContext
而不是
AddDbContextPool
是否有任何问题,因为我没有找到如何使
AddDbContextPool
singleton?起初没有。我试图坚持使用池来提高性能。但是无论如何,
AddDbContext
不会有同样的问题,因为它也注册为作用域服务吗?此外,
DbContext
永远不应该是单例,应该小心地处理它们。这就是为什么我试图找到一种动态使用它的方法。@JoãoMenighin,好的,让我进一步检查一下我能为您做些什么。
services.AddDbContext<MyContext>((serviceProvider, options) =>
        {
            options.UseSqlServer(connectionString);
            options.UseInternalServiceProvider(serviceProvider);
        }, ServiceLifetime.Singleton); // <-- Here it is