Dbcontext 注册为“范围”或“瞬态”是否会影响关闭数据库连接

我对 ASP.NET MVC 中的 DI 有基本的了解,但是有一个问题很困扰我。将 Dbcontext 注册为“作用域”或“瞬态”有什么区别吗?下面是一个典型的 mvc 应用程序的一些代码:


public class EmployeeController : Controller

{

    private EmployeeContext _context;


    public EmployeeController(EmployeeContext context)

    {

        _context = context;

    }


    public ActionResult Index()

    {

        return View(context.Employees.ToList());

    }

    

    ...//other action methods that access context's DbSet

}

假设我们注册EmployeeContext为临时服务。运行应用程序后,应用程序将侦听任何传入的请求。假设发生了对默认 /Home/Index 的 http 请求,因此EmployeeController 需要创建一个新实例。EmployeeContextDI首先会向控制器的构造函数提供一个实例。_context也适用于所有其他操作方法,并且没有任何其他地方需要创建新EmployeeContext服务。


所以请求完成后,也会_context被处理掉。这和作用域服务不是一样的效果吗?我们打算将其注册为“瞬态”服务,最终它的工作方式就像“范围内”服务。看来我们将 Dbcontext 注册为“作用域”或“瞬态”并不重要。


呼唤远方
浏览 72回答 2
2回答

一只甜甜圈

如果您不使用任何其他注入服务(这些服务也使用您的 DBContext),那么作用域服务和瞬态服务之间没有区别。但是,如果您使用其他注入服务,并且 DBContext 上有“瞬态”,则每个服务都会获得自己的实例。为了避免这种情况,您应该始终在 DBContext 上使用“scoped”。在具有以下代码的示例中,对于“瞬态”EmployeeContext,每个请求都会有两个实例:public class MyService : IMyService { public MyService(EmployeeContext context) {  // ... }}public class EmployeeController : Controller{    private EmployeeContext _context;    private _myService;    public EmployeeController(EmployeeContext context, IMyService myService)    {        _context = context;        _myService = myService;    }    public ActionResult Index()    {        return View(context.Employees.ToList());    }    ...//other action methods that access context's DbSet}

胡子哥哥

从官方文档来看,DBContext被设计为短暂且非线程安全的。如果 DBContext 实例处理得当,它们不会导致并发问题。通常,底层并发问题应该来自 SQL TCP 连接池。创建多少个 DBContext 实例对于并发问题并不重要。但它确实在堆中创建对象,这意味着如果您可以完全控制代码流并保证不会出现任何线程安全问题,则应该限制 DBContext 对象的创建。但根据我的理解,不应在请求线程之间共享实例,因为这会导致线程安全问题的损坏。
打开App,查看更多内容
随时随地看视频慕课网APP