IQueryable<T> Results Broken?

Topics: ASP.NET Web API
Apr 2, 2012 at 12:13 PM
Edited Apr 2, 2012 at 12:13 PM


Looking over some of my previously implemented examples it looks like the IQueryable<T> oData style navigation features are not working properly anymore. It looks like some things work some things don't (but used to).

Specifcally I have a controller method like this:

 

        [HttpGet]
        public IQueryable<Album> SortableAlbums()
        {
            var albums = AlbumData.Current;
            return albums.AsQueryable();
        }

 

and then use a URL like this to access it.

http://localhost/AspNetWebApi/albums/rpc/SortableAlbums?$orderby=YearReleased&$top=2

Neither of those two oData driectives seem to work, but they used to.

Is this broken or has support for this been removed?

+++ Rick ---

Apr 2, 2012 at 4:36 PM

Rick, we recently implemented a change so that you need to explicitly annotate your action with the new [Queryable] filter attribute. To reenable this functionality globally you could also add your filter to the global filter collection on HttpConfiguration.

The change is intended to give you more control over the behavior of the application and avoid too many things that happen automagically. Let us know what you think.

Apr 2, 2012 at 5:10 PM

You should consider needing to use .AsQueryable() as a potential red flag for this feature.

The efficient application of OData query syntax needs an implementation of IQueryable that can turn the query into efficient SQL statements (both EF and LINQ to SQL can do this). So if your data source (AlbumData.Current) is already one of these, you should probably change the signature to be IQueryable<T> rather than IEnumerable<T>, and get rid of the call to .AsQueryable(); if your implementation isn't one of the optimized queries, then you might want to reconsider whether letting the user specify query parameters will be a good thing or not (if the whole data is loaded from the database into memory before the query is applied, you're going to be wasting SQL bandwidth and download time, as well as web server memory and CPU).

Apr 2, 2012 at 9:45 PM

Marcin - adding [Queryable] to the method made it work indeed. 

I think that's a good change. I was wondering about the implications of having an open querying format accessible like that on any request that returns IQueryable<T>. But then the I also think *normally* you wouldn't return IQueryable<T> but IEnumerable<T> or a hard list/dictionary, no? So wouldn't IQueryable<T> already indicate that you might want to filter the data?

Brad - makes sense and totally understand. In this case I'm working off static sample data that stands in for a full entity model so normally I wouldn't expect to use ToQueryable(). Reminds me to add a note to an article though :-) 

Thanks guys!

+++ Rick ---