我有这个存储库方法:
public IQueryable<TModel> GetAll()
{
using (var context = new DatabaseContext())
{
return context.Set<TModel>().AsQueryable();
}
}
其中TModel
是艺术家模型..无论如何
然后我在我的控制器中执行此操作:
// GET api/artist
[Queryable]
public IQueryable<ArtistModel> Get()
{
return _repo.GetAll().AsQueryable();
}
现在..如果我要更改存储库方法以返回List并为我的结果添加.ToList
..那么这将很有效。但是无论什么OData查询进来..我仍然会首先执行“获取所有查询”..将它们转换为列表然后我将对该列表执行我的OData查询..
这似乎是完全错误的..我想要做的是确保OData查询在我尝试从数据库中获取数据的同时执行..所以我只得到非常具体的结果匹配查询..而不是后来被查询的大量数据..
现在我遇到了DbContext
在使用之外被处理掉的问题..但我仍然需要关闭DbContext
以及某些地方,有些如何...
有什么想法吗?
答案 0 :(得分:2)
您可以通过多种方式启用可查询的Web API,
将[Queryable]
属性放在您的操作上。您的操作可以返回以下内容之一 - IEnumerable<T>
,IQueryable<T>
,HttpResponseMessage
,内容为ObjectContent<IQueryable<T>>
或ObjectContent<IEnumerable<T>>
,Task<IQueryable<T>>
,{{ 1}},Task<IEnumerable<T>>
具有与之前相同的限制。
通过Task<HttpResponseMessage>
启用全局查询。这样可以查询返回configuration.EnableQuerySupport()
。
按照here使用IQueryable<T>
并自行手动应用查询。
关于ODataQueryOptions<T>
处理问题,我们以一种懒惰的方式很晚地评估查询 - 当格式化程序将响应写入流时。因此,您不应在行动中处置DbContext
。而是将它与控制器一起配置,即覆盖控制器的DbContext
方法并将其丢弃。 Web API负责控制器的生命周期,并在请求完成处理后处理控制器。此外,您也可以使用Dispose
方法,在请求处理完毕后处理任何资源。
答案 1 :(得分:1)
web api的可查询扩展的最新版本有点令人困惑,因为它与以前的版本有很大的不同。在新版本中,您需要显式启用可查询支持或使用新的查询选项类。 See this
编辑:有些代码,因为我现在在办公桌
public IQueryable<TModel> GetAll(ODataQueryOptions opts)
{
var db = _repo.GetAll();
return (IQueryable<TModel>) opts.ApplyTo(db);
}