EFCore依赖注入数据库连接寿命

3
尝试使用EFCore替代EF 6,我很难理解在使用依赖注入来管理我的DB上下文时数据库生命周期是如何发生的。
在EF 6中,我习惯于手动打开连接并利用using语句来使用其dispose方法。在这种情况下,数据库生命周期的反应对我来说似乎很清晰。
(using var db = new DatabaseContext())
{}

使用EFCore,建议的方式是在启动时将数据库上下文类添加为服务。
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

然后通过依赖注入在控制器中获取上下文。
    private readonly ApplicationDbContext context;

    public HomeController(ApplicationDbContext context, ILogger<HomeController> logger)
    {
        this.context = context;
    }

以这种方式,连接池是何时开始的?我的连接何时打开,它的寿命是多久?它是在应用程序启动时打开并在停止时关闭吗?如果使用MVC,它会在控制器方法被调用时打开吗?在活动查询时呢?
我在SF Core 2.0文档中找到了一个简短的参考提示,介绍了DBContext池背后正在发生的事情。
“在ASP.NET Core应用程序中使用EF Core的基本模式通常涉及将自定义DbContext类型注册到依赖注入系统中,并通过控制器中的构造函数参数获取该类型的实例。这意味着为每个请求创建一个新的DbContext实例。”

https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0

这是否意味着对于控制器的默认请求,无论我是否使用它,数据库上下文都会在请求管道中打开?假设当请求返回时它被关闭。
请问有人可以帮我理解使用此模式时数据库连接的生命周期吗?如果这是一个重复的问题,请帮忙标记并指向我详细阅读的地方。我已经花了一些时间进行研究,但似乎所有我能找到的文章都只是概述,或者我可能用错了关键词。
1个回答

2
默认情况下,每个HTTP请求将创建并使用单个DbContext。在DbContext的生命周期内可以多次打开和关闭连接,但如果DbContext启动了事务,则相同的基础连接将保持打开状态,并在事务的生命周期内被重用。
当您创建一个DbContext时,它不会立即初始化,也不会立即打开其连接。
AddDbContext扩展方法默认使用作用域生命周期注册DbContext类型。这在ASP.NET Core应用程序中是安全的,因为在给定时间只有一个线程执行每个客户端请求,并且因为每个请求都获得一个单独的依赖注入作用域(因此获得一个单独的DbContext实例)。然而,任何明确执行多个并行线程的代码都应确保不会同时访问DbContext实例。
通过依赖注入隐式共享DbContext实例跨多个线程的做法请参阅此处

1
所以在MVC结构中,一个请求被路由到我的控制器,在其中我注入了服务:底层提供程序然后打开,并将保持在接受状态,直到我的请求的上下文关闭(控制器返回)? 非常感谢您的快速回复。 - Travis Acton
谢谢你的问题和答案。我对更好地理解这个过程也非常感兴趣。在一个dotnet core API中,通过依赖注入使用DbContext,我是否需要手动关闭连接?因为它是通过注入传递的单个DbContext实例,如果我在类方法中打开一个事务,即使我实例化不同的对象,连接也会是相同的吗? - Daniel Melo
这取决于使用的事务API。您可能需要强制DbConnection在DbContext的整个持续时间内保持打开状态。具体细节会因提供程序而异。不过,TransactionScope应该适用于所有提供程序。根据您的具体情况,请提出一个新问题。 - David Browne - Microsoft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接