I am building a pager in my UI that reuses a
DataServiceQuery<MyEntityType> built in another window when it comes to the end of its cached results. My current implementation attempts to do something like:
query = query.Skip(index*page_size).Take(page_size)
where query was previously defined using a dynamic LINQ query as:
query = Where(queryString, queryValues.ToArray()).Take(page_size)
This throws a NotSupportedException: The skip query option cannot be specified after the top query option.
Is there a way to remove the Take (top) portion of the DataServiceQuery, add then Skip(), and then re-add the Take()?
You can manipulate the expression tree in the IQueryable (DataServiceQuery implements IQueryable). For example:
DemoService ctx = new DemoService(new Uri("http://services.odata.org/OData/OData.svc/")); DataServiceQuery<Product> products = ctx.Products; DataServiceQuery<Product> q = (DataServiceQuery<Product>)products.Where(p => p.Name == "Bread").Skip(10); MethodCallExpression skipCall = (MethodCallExpression)q.Expression; q = (DataServiceQuery<Product>)q.Provider.CreateQuery<Product>(skipCall.Arguments); Console.WriteLine(q);
This code constructs a query with Skip at the end. Then it takes the query and removes the Skip from it. Note that this is "hacky" in that it relies on the Skip being last (direct cast to MethodCallExpression).