如何从oData V4 api操作返回IQueryable

时间:2016-11-01 12:50:04

标签: c# entity-framework rest odata

遵循教程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;
}

2 个答案:

答案 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自动运行。