C# 如何将DbContextPool与Singleton一起使用?
在我的应用程序中,我使用NMS和ActiveMQ进行集成。 我有一些侦听器是单例的,它们侦听一些消息队列。 在收到消息后,侦听器应处理该消息并将其记录到数据库中。 我的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) =>
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