【问题标题】:Entity Framework Core - disposed when trying to run 2nd QueryEntity Framework Core - 在尝试运行第二个查询时释放
【发布时间】: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 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。

我很难理解为什么会这样。谁能给我指点来解决这个问题?

非常感谢 西蒙

【问题讨论】:

    标签: c# entity-framework-core


    【解决方案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 中间件。

    【讨论】:

    • 我不确定这是否属实。单个请求的生命周期与对数据库的单个调用不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多