实体框架:如何跨多个线程使用DbContext的多个实例

时间:2017-05-18 07:09:35

标签: c# asp.net-mvc multithreading entity-framework autofac

我正在使用Autofac注入依赖项,我的应用程序需要在后端工作,我使用Quartz来触发后台工作程序。

我使用以下代码:

builder.RegisterType<AppContext>()
               .AsSelf().InstancePerDependency()

允许每个工作进程(线程)拥有DbContext类的新实例,我这样做是因为DbContext类不是线程安全的。

当我去更新或创建它所说的内容

时,真正的问题就开始了
  

在ObjectStateManager中找不到对象

我已经看到了一些解决方案,比如分离和附加实体。但就我而言,我的存储库方法正由前端(Asp.Net MVC)使用。我不想复制那些方法,一个特定于来自Web应用程序的数据库调用,另一个来自后台工作者。

任何解决方案?

1 个答案:

答案 0 :(得分:3)

使用InstancePerDependency(),Autofac将为每个工作人员创建一个DbContext,但每次创建的对象都需要一个。假设您使用3个存储库,并且每个存储库都有一个上下文构造函数参数,这意味着三个不同的上下文(更不用说您必须自己管理处理的事实,并且您可能希望为每个Web请求创建一个上下文,这个不允许你这样做。

您需要的是这个Autofac-Quartz集成包:

https://github.com/alphacloud/Autofac.Extras.Quartz

根据文档,这会为每个作业创建一个生命周期范围。因此,如果将上下文注册为InstancePerLifetimeScope(),则一个作业(具有自己的生命周期范围)内的所有内容都将获得相同的上下文对象。这可能会解决您的问题。