Entity Framework Core - 在尝试运行第二个查询时释放
Posted
技术标签:
【中文标题】Entity Framework Core - 在尝试运行第二个查询时释放【英文标题】:Entity Framework Core - disposed when trying to run 2nd Query 【发布时间】:2019-05-13 23:45:01 【问题描述】:我在处理数据库上下文时遇到问题。我在配置服务方法中设置了如下数据库。代码已经过简化,希望它更易于阅读。
public void ConfigureServices(IServicesCollection services)
Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Database1")));
Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Database2")));
Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Database3")));
Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Database4")));
Services.AddScoped<IQueryService1, ConcreteService1>();
Services.AddScoped<IQueryService1, ConcreteService2>();
Services.AddScoped<IQueryService1, ConcreteService3>();
Services.AddScoped<IQueryService1, ConcreteService4>();
现在我在其中一个控制器中注入所需的相关服务。
[Produces("application/json")]
[Route("api/[controller]/[action]
public class DigitalFinesController : Controller
private readonly IQueryService1 _Service1;
public DigitalFinesController(IConfiguration configuration, IQueryServices1 QueryService1)
_Service1 = QueryService1;
[Authorize]
[HttpPost]
[ActionName("SubmitFine")]
[ProducesResponseType(200)]
[ProducesResponseType(401)]
public async Task<IActionResult> SubmitFine([FromBody] Models.DigitalFine fine)
//This is a simple version of my issue
var vehicles = _Service1.Vehicles.FirstOrDefault(p=> p.vrm == "OX7 DFG");
if(vehicle == null)
return BadRequest("Vehicle is missing");
var fleet = _Service1.Fleets.FirstOrDefault(p=> p.Code = "MyCode");
一旦我进入第二个查询,我就会得到以下异常
System.ObjectDisposedException: '无法访问已处置的对象。此错误的一个常见原因是释放从依赖注入中解析的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文上调用 Dispose() 或将上下文包装在 using 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。
我很难理解为什么会这样。谁能给我指点来解决这个问题?
非常感谢 西蒙
【问题讨论】:
【参考方案1】:我认为这可能与您的注册方式有关。尝试使用AddSingleton
而不是AddScoped
注册它
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2#service-lifetimes-and-registration-options
作用域
范围内的生命周期服务为每个请求创建一次。
警告
在中间件中使用作用域服务时,将服务注入 Invoke 或 InvokeAsync
方法。不要通过构造函数注入进行注入,因为它会强制服务表现得像一个单例。有关详细信息,请参阅 ASP.NET Core 中间件。
单例
单例生命周期服务在第一次被请求时创建(或者在运行ConfigureServices
并使用服务注册指定实例时)。每个后续请求都使用相同的实例。如果应用程序需要单例行为,建议允许服务容器管理服务的生命周期。不要实现单例设计模式并提供用户代码来管理类中对象的生命周期。
警告
从单例解析作用域服务是很危险的。可能会导致服务在处理后续请求时状态不正确。
【讨论】:
您使用不同的文档得出了与我相同的答案。 +1 OP 也可以使用Transient
而不是 singleton
,但这取决于他们。【参考方案2】:
.AddScoped
将在请求生命周期后释放,尝试更改为 singleton
或 transient
:
请参阅文档: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
在这个部分:
在示例应用程序中,IMyDependency 服务注册到 具体类型 MyDependency。注册范围服务 生命周期到单个请求的生命周期。服务生命周期是 本主题稍后将介绍。
警告
在中间件中使用作用域服务时,将服务注入 Invoke 或 InvokeAsync 方法。不要通过构造函数注入 注入,因为它强制服务表现得像一个单例。 有关详细信息,请参阅 ASP.NET Core 中间件。
【讨论】:
我不确定这是否属实。单个请求的生命周期与对数据库的单个调用不同。以上是关于Entity Framework Core - 在尝试运行第二个查询时释放的主要内容,如果未能解决你的问题,请参考以下文章
在 Entity Framework Core 中使用 SQL 视图
在 Entity Framework Core 中使用 [ComplexType]
Entity Framework优化一:引发了“System.Data.Entity.Core.EntityCommandExecutionException”类型的异常