I have this repository method:
public IQueryable<TModel> GetAll()
{
using (var context = new DatabaseContext())
{
return context.Set<TModel>().AsQueryable();
}
}
where TModel
is an artist-model.. anyway
And then I have this action in my controller:
// GET api/artist
[Queryable]
public IQueryable<ArtistModel> Get()
{
return _repo.GetAll().AsQueryable();
}
Now.. if I would change the repository method to return a List and also add .ToList
for my result.. then this would work great. But then no matter what OData query comes in.. I would still first execute a "get all query".. turn them into a list and then I would execute my OData query against that list..
Which seems just plain wrong.. what I would like to do is to make sure that the OData query gets executed the same time as I'm trying to fetch data from the database.. so I only get the very specific result matching the query.. and not a huge bunch of data that then later on gets queried..
For now I have the problem with the DbContext
getting disposed once outside the using.. but I still need to close the DbContext
as well some where, some how..
Any ideas?
You can enable web API queryable through a couple of ways,
Put the
[Queryable]
attribute on your action. Your action can return one of these -IEnumerable<T>
,IQueryable<T>
,HttpResponseMessage
with the content being anObjectContent<IQueryable<T>>
orObjectContent<IEnumerable<T>>
,Task<IQueryable<T>>
,Task<IEnumerable<T>>
,Task<HttpResponseMessage>
with the same restrictions as earlier.Enable querying globally by doing
configuration.EnableQuerySupport()
. This would enable querying for all methods that return anIQueryable<T>
.Use
ODataQueryOptions<T>
as mentioned here and manually applying the query yourself.And regarding the
DbContext
disposal issue, we evaluate the query very late in a lazy fashion - when the formatter is writing the response to the stream. So, you should not dispose theDbContext
in your action. Instead, dispose it along with the controller i.e override the controller'sDispose
method and dispose it there. Web API takes care of the controllers life time and disposes the controller when the request is done processing. Also, you can useRequest.RegisterForDispose
method too, to dispose any resources when the request is done processing.The latest version of the queryable extension of web api is kind of confusing, since it is so different from previous versions. In the new version you need to either explicitly enable queryable support or use the new query options class. See this
Edit:Some code this since I am now at a desk