[尝试开始使用EFCore替代EF 6,并且我很难理解将依赖注入用于我的数据库上下文时数据库生命周期是如何发生的。
在EF 6中,我熟悉手动打开连接并通过using语句利用它的dispose方法。对我来说,数据库生命周期如何以这种方式做出反应似乎很清楚。
(using var db = new DatabaseContext())
{}
使用EFCore,我理解推荐的方式是在启动时将db上下文类添加为服务
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://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0
这是否意味着对于进入我的控制器的默认请求,无论我是否使用它,都在请求管道中打开数据库上下文?假设返回请求时它是关闭的。
有人使用此模式可以帮助我了解数据库连接寿命吗?如果这是一个重复的问题,请帮助标记并指向我可以详细阅读的地方。我花了一些时间进行研究,但似乎所有可以找到的文章都只是掩盖了这一点,否则我可能会使用错误的关键字进行搜索。
默认情况下,将创建一个DbContext并将其用于每个HTTP请求。在DbContext的生存期内,可以多次打开和关闭连接,但是,如果DbContext启动事务,则相同的基础连接将保持打开状态,并在事务的生存期内被重用。
创建DbContext时,不会立即对其进行初始化,也不会立即打开其连接。
AddDbContext扩展方法向DbContext类型注册一个默认为scoped生存期。
这可以避免ASP.NET Core中的并发访问问题应用程序,因为只有一个线程执行每个客户端给定时间的请求,并且因为每个请求都得到一个单独的请求依赖项注入范围(因此还有一个单独的DbContext实例)。
但是任何可以并行并行执行多个线程的代码应该确保从未访问过DbContext实例同时。
Implicitly sharing DbContext instances across multiple threads via dependency injection