ObjectDisposedException 尝试实施 DDD 项目

ObjectDisposedException trying implement DDD project

当我尝试 return 我的 orderList 作为 IQueryable 时,我收到以下错误:

"ObjectDisposedException: 无法访问已处置的对象。导致此错误的一个常见原因是处置从依赖项注入解析的上下文,然后尝试在应用程序的其他位置使用相同的上下文实例。如果您在上下文中调用 Dispose(),或者将上下文包装在 using 语句中。如果您使用依赖注入,则应该让依赖注入容器负责处理上下文实例。 对象名称:'KeplerContext'"

Ps。如果我直接在我的控制器上使用 DbContext,一切正常。

有帮助吗?提前致谢。

我的控制器 class 是:

public class OrderController : Controller
{
    public readonly IAppOrder _IAppOrder;
    public readonly UserManager<User> _userManager;

    // Ps.: Directly for the context works fine
    //private readonly KeplerContext _context;

    public OrderController(IAppOrder IAppOrder, UserManager<User> userManager) //, KeplerContext context)
    {
        _IAppOrder = IAppOrder;
        _userManager = userManager;

        // Ps.: Directly for the context works fine
        //_context = context;
    }

    public async Task<IActionResult> Index(string sortOrder, int? pageNumber)
    {
        var user = await _userManager.GetUserAsync(User);

        var orderList = _IAppOrder.OrderList(user);
            ^^^^

        if (!orderList.Any())
        {
            TempData["info"] = "no orders.";
        }
        else
        {
            var orderActive = await _IAppOrder.GetLastOrder(user);

            if (orderActive.IdOrderStatus <= 5)
            {
                return RedirectToAction(nameof(OrderController.Order), "Order", new { Area = "App", Id = orderActive.IdOrder });
            }
        }

        // paging
        ViewData["CurrentSort"] = sortOrder;
        ViewData["NumSort"] = String.IsNullOrEmpty(sortOrder) ? "num_asc" : "";

        switch (sortOrder)
        {
            case "num_asc":
                orderList = orderList.OrderBy(s => s.IdOrder);
                break;
            default:
                orderList = orderList.OrderByDescending(s => s.IdOrder);
                break;
        }
        int pageSize = 8;

        return View(await PagingHelper<Order>.CreateAsync(orderList.AsNoTracking(), pageNumber ?? 1, pageSize));
    }
}

我的申请class:(Ps。我正在使用DDD,其他人class我已经省略以简化问题):

    public IQueryable<Order> OrderList (User user)
    {
        return _IOrder.OrderList(user);
    }

我的仓库class:

public class RepositoryOrder : RepositoryGenerics<Order>, IDomOrder
{
    private readonly DbContextOptions<KeplerContext> _optionsBuilder;

    public RepositoryOrder()
    {
        _optionsBuilder = new DbContextOptions<KeplerContext>();
    }

    public IQueryable<Order> OrderList(User user)
    {
        using var db = new DbContext(_optionsBuilder);

        var result = db.Order
            .Include(p => p.IdOrderStatusNavigation)
            .Include(p => p.IdNavigation)
            .Where(u => u.Id == user.Id)
            .AsQueryable();
         
        return result;
               ^^^^^^ <<< Error happens here!!!
    }
}

我的存储库泛型 class:

public class RepositoryGenerics<T> : IDomGeneric<T>, IDisposable where T : class
{
    private readonly DbContextOptions<KeplerContext> _OptionsBuilder;

    public RepositoryGenerics()
    {
        _OptionsBuilder = new DbContextOptions<KeplerContext>();
    }

    public async Task Add(T obj)
    {
        using var data = new KeplerContext(_OptionsBuilder);

        await data.Set<T>().AddAsync(obj);
        await data.SaveChangesAsync();
    }

    public async Task Delete(T obj)
    {
        using var data = new KeplerContext(_OptionsBuilder);

        data.Set<T>().Remove(obj);
        await data.SaveChangesAsync();
    }

    public async Task<T> GetEntityById(int Id)
    {
        using var data = new KeplerContext(_OptionsBuilder);

        return await data.Set<T>().FindAsync(Id);
    }

    public async Task<List<T>> List()
    {
        using var data = new KeplerContext(_OptionsBuilder);

        return await data.Set<T>().AsNoTracking().ToListAsync();
    }

    public async Task Update(T obj)
    {
        using var data = new KeplerContext(_OptionsBuilder);

        data.Set<T>().Update(obj);
        await data.SaveChangesAsync();
    }


    // https://docs.microsoft.com/pt-br/dotnet/standard/garbage-collection/implementing-dispose
    bool disposed = false;
    SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

    // "Dispose Pattern" 
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            handle.Dispose();
        }

        disposed = true;
    }
}

Startup.cs 内的依赖注入:

        // Repository
        services.AddSingleton(typeof(IDomGeneric<>), typeof(RepositoryGenerics<>));
        ...
        services.AddSingleton<IDomOrder, RepositoryOrder>();
        ...

        // Inteface da Application
        ...
        services.AddSingleton<IAppOrder, AppOrder>();
        ...

        // Service Domain
        ...
        services.AddSingleton<IServiceOrder, ServiceOrder>();
        ...

您的 RepositoryOrder.OrderList 正在返回 IQueryable,这意味着您 在该方法的范围内执行查询。所以我相信您所看到的是,当最终执行查询时,DbContext 已经被处理掉了,因为一旦您离开方法范围,它就会被处理掉。

您可以调用 ToList 而不是 AsQueryable