遵循教程here我正在尝试返回IQueryable,但是我收到错误由于DbContext已被处理,因此无法完成操作
public class ProductsController : ODataController
{
[EnableQuery]
public IQueryable<Product> Get()
{
return GetRepository<Product>().GetQueryable();
}
}
GetRepository()是更大的通用DI和工作单元模式类的一部分,基本上是
public Repository(DbContext context)
{
Context = context;
DbSet = Context.Set<T>();
}
public virtual IQueryable<T> GetQueryable()
{
IQueryable<T> query = DbSet;
return query;
}
答案 0 :(得分:1)
如果仔细查看您提供的链接中给出的示例,您可以看到它们具有响应方法之外的上下文,并且在控制器上调用Dispose方法之前不会处理它。
public class ProductsController : ODataController
{
ProductsContext db = new ProductsContext();
[EnableQuery]
public IQueryable<Product> Get()
{
return db.Products;
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
最有可能的是,您在GetRepository()或GetQueryable()方法中处理创建的上下文。例如,应用using
。
答案 1 :(得分:1)
从控制器返回IQueryable时,您无法控制何时运行IQueryable。发生的事情是你的DbContext在Web API管道开始运行IQueryable并返回结果之前被处理掉。
您正在使用GetRepository执行的操作称为服务定位器模式。但是,Web API具有执行依赖注入的机制,这将使您可以更加确定地控制资源的生命周期。
https://www.asp.net/web-api/overview/advanced/dependency-injection
使用这种方法,构造函数注入您的服务(GetRepository的返回类型),然后在控制器上覆盖Dispose,以便清理构造函数注入的服务。一旦Web控制器完成运行并从IQueryable返回结果,Web API将在您的控制器上调用Dispose,因此您的生命周期问题将得到修复。
NuGet上有许多常见的IOC容器包装器,允许它们使用Web API自动运行。