首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ObjectDisposedException尝试实施DDD项目

ObjectDisposedException尝试实施DDD项目
EN

Stack Overflow用户
提问于 2020-11-25 18:36:54
回答 1查看 49关注 0票数 0

当我试图以IQueryable的形式返回我的IQueryable时,我会得到以下错误:

"ObjectDisposedException:无法访问已释放的对象。导致此错误的一个常见原因是处理了一个从依赖项注入中解析出来的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文上调用Dispose(),或者将上下文包装在using语句中,则可能会发生这种情况。如果使用依赖项注入,则应该让依赖项注入容器处理上下文实例。对象名称:'KeplerContext'“

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

有人帮忙吗?提前谢谢。

我的控制器类是:

代码语言:javascript
复制
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));
    }
}

我的申请课:(Ps。我正在与DDD合作,其他课程我忽略了简化这个问题):

代码语言:javascript
复制
    public IQueryable<Order> OrderList (User user)
    {
        return _IOrder.OrderList(user);
    }

我的存储库类:

代码语言:javascript
复制
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!!!
    }
}

我的存储库泛型类:

代码语言:javascript
复制
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://learn.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内部的依赖注入:

代码语言:javascript
复制
        // Repository
        services.AddSingleton(typeof(IDomGeneric<>), typeof(RepositoryGenerics<>));
        ...
        services.AddSingleton<IDomOrder, RepositoryOrder>();
        ...

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

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

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-25 19:57:25

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

相反,您可以调用ToList而不是AsQueryable

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65010803

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档