Search code examples
.netasp.net-web-apiexpressionodata

For OData queries, is $filter guaranteed to execute before $skip?


I could not find mention in the OData protocol documentation if a $filter operation is always applied before a $skip operation. Clearly, it makes sense to do so when implementing a consistent page retrieval algorithm.

My concern is that an expression tree doesn't impose such a constraint. For instance, the following two queries will generally produce different results.

IQueryable<string> query = (new[] { "aaa", "eee", "bbbb", "cccc", "dddd" }).AsQueryable();

query.Where(arg => arg.Length > 3).Skip(1);
query.Skip(1).Where(arg => arg.Length > 3);

I've done some simple testing with the ASP.NET Web API RC implementation for OData, and it does apply $filter before $skip, regardless of where the operators appear in the query string. Is this true in general though?


Solution

  • MS-ODATA (the OSP spec for OData) states: A data service URI with more than one query option present MUST be evaluated as if the query options were applied to the resource(s) identified by the resource path section of the URI, in the following order: $format, $inlinecount, $filter, $orderby, $skiptoken, $skip, $top, $expand.

    I think there's actually a bug or two in the spec (which should be addressed in the next spec update) - I added this comment: How can $inlinecount be effective before $filter, and how can $filter/$orderby be effective before $expand?

    At any rate, you can assume that the spec does order the system query options, and it's currently a MUST in the spec, so any server that claims to support OData should consistently evaluate $filter before $skip or $top.