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 将在请求生命周期后释放,尝试更改为 singletontransient

请参阅文档: 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”类型的异常

Entity Framework Core快速开始

Entity Framework Core 快速开始

张高兴的 Entity Framework Core 即学即用:创建第一个 EF Core 应用