【发布时间】:2018-06-27 15:44:44
【问题描述】:
这与以下有关,但并不完全相同: EF. The connection was not closed. The connection's current state is connecting
我知道这个错误可能是处理 DbContext 时出现竞争条件的结果。
以下是导致我出现问题的原因的简化示例,以及我的解决方案。我只是不太明白为什么我的解决方案有效:
Startup.cs
services.AddDbContext<MyDbContext>(options => options.UseSqlServer("ConnString"));
// This will cause the "Connection was not closed..." error.
services.AddSingleton<IHostedService, SomeBackgroundService>(provider =>
new SomeBackgroundService(provider.GetRequiredService<MyDbContext>());
// Instead, I instantiate the DbContext here instead of letting DI do it
// and this eliminates the error.
services.AddSingleton<IHostedService, SomeBackgroundService(provider =>
new SomeBackgroundService(new MyDbContext(
new DbContextOptionsBuilder<MyDbContext>().UseSqlServer("ConnString").Options));
在我的SomeBackgroundService 内部,我执行一些异步查询,同时在控制器方法内部执行其他查询。
但是,既然如此,不应该使用provider.GetRequiredService<T> 以同样的方式实例化一个新的 DbContext 吗?
【问题讨论】:
-
你不应该将单例与
DbContext结合使用。 -
感谢您的回复。我想我的问题更像是,即使我 确实 有一个单例,我认为 provider.GetRequiredService
会创建一个 DbContext 实例以注入到我的单例类中?跨度> -
是的,这实际上使
DbContext也是一个单例。现在,如果你尝试在 HTTP 请求中使用它,它将会爆炸。 -
我明白你在说什么。原谅我,我还是有点糊涂。使用 DbContext 的
IHostedService是后台任务,所以我的想法是后台任务并没有真正被 HTTP 请求“访问”,只是在后台运行。您是说在注册单例的上下文中使用的provider.GetRequiredService<T>实际上不会创建 DbContext 实例,而是获取使用 DI 容器注册的现有 DbContext ——这将基于services.AddDbcontext<T>?
标签: c# asp.net-core dependency-injection entity-framework-core