繁体   English   中英

C#:使用 IQueryable 注入 DbContext 时,无法访问 ASP.NET 核心中已处置的 object

[英]C#: Cannot access a disposed object in ASP.NET Core when injecting DbContext with IQueryable

我收到以下错误。 目前遵循 Async/await 模式并使用 IServiceScopeFactory。 试图将 Repo 与 IQueryable 链接起来。

接收错误如下:

无法访问已处置的 object。 此错误的一个常见原因是释放从依赖注入中解析的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。 如果您在上下文上调用 Dispose() 或将上下文包装在 using 语句中,则可能会发生这种情况。 如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。 Object 名称:“PropertyContext”。

存储库:

public class AddressRepository
{
    private readonly IServiceScopeFactory _factory;
    public AddressRepository(IServiceScopeFactory factory) : base(factory)
    {
        _factory = factory;

    [EnableQuery]
    public IQueryable<LkAddressType> GetAddressTypes()
    {
        using (var scope = _factory.CreateScope())
        {
            var db = scope.ServiceProvider.GetService<PropertyContext>();
            return db.LkAddressType.AsNoTracking();
        }
    }

应用服务:

    public async Task<AddressTypeResponse> GetAddressTypes()
    {
        var data = await (_addressRepository.GetAddressTypes()).ToListAsync();
        var mapped = _mapper.Map<ICollection<AddressTypeModel>>(data);
        var dto = _mapper.Map<ICollection<AddressTypeDto>>(mapped);
        return new AddressTypeResponse {Body = dto};
    }

Controller:

    [HttpGet("AddressType")]
    public async Task<ActionResult<AddressTypeResponse>> GetAddressTypes()
    {
         return Ok(await _service.GetAddressTypes());
    }

目前使用 Net Core 2.2、Entity Framework Core 和 OData。

Scope 自动处置实现它创建的IDisosable的作用域(和瞬态)对象,因此当GetAddressTypes结束时,将处置scopedb 因此,您要么需要返回一些客户端将处理的包装器,要么具体化查询并从方法返回结果:

[EnableQuery]
public Task<List<LkAddressType>> GetAddressTypes()
{
    using (var scope = _factory.CreateScope())
    {
        var db = scope.ServiceProvider.GetService<PropertyContext>();
        return await db.LkAddressType.AsNoTracking().ToListAsync();
    }
}

或者将您的上下文直接注入存储库并让框架确定范围:

public class AddressRepository
{
    private readonly PropertyContext _ctx;
    public AddressRepository(PropertyContext ctx,IServiceScopeFactory factory) : base(factory)
    {
        _ctx= ctx;
     }

    [EnableQuery]
    public IQueryable<LkAddressType> GetAddressTypes()
    {
        return _ctx.LkAddressType.AsNoTracking();
    }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM