ObjectDisposedException尝试实现DDD项目



当我试图将orderList返回为IQueryable时,我会得到以下错误:

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

Ps。如果我直接在控制器上使用DbContext,一切都会很好。

有什么帮助吗?提前谢谢。

我的控制器类是:

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,为了简化问题,我省略了其他类(:

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

我的存储库类:

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!!!
}
}

我的存储库泛型类:

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:内部的依赖项注入

// 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

最新更新