Lets assume you have the following function in an OData controller that calls
a stored procedure / function in Entity Framework and the the function has
"EnableQuery" attribute.
Also, assume that the stored procedure supports paging and will only return a
subset of data along with an output parameter that contains the "true total"
row count.
[HttpPost]
[EnableQuery]
public PageResult<SomeObject> SomeFunction(ODataQueryOptions<SomeObject> options, ODataActionParameters parameters)
{
// Get the paging settings from ODataActionParameters since they are not shown on the ODataQueryOptions. Maybe there will be some fix for this in the future.
int pageSize = (int)parameters["pageSize"];
int take = (int)parameters["take"];
int skip = (int)parameters["skip"];
int page = (int)parameters["page"];
// Apply page size settings
ODataQuerySettings settings = new ODataQuerySettings();
settings.PageSize = pageSize;
// Create a temp result set to hold the results from the stored procedure
var totalRows = new System.Data.Entity.Core.Objects.ObjectParameter("TotalRows", typeof(Int64));
var tempResults = db.SomeStoredProc(skip, take, totalRows).ToList(); // ToList is required or you will receive an enumeration more than once error on the PageResult
// Apply the query options. For now this is only needed to get the correct count since the options does not seem to contain the TOP / SKIP when using OData parameters.
IQueryable results = options.ApplyTo(tempResults.AsQueryable(), settings);
// Custom paging. EXAMPLE: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options
return new PageResult<SomeObject>(tempResults,
Request.ODataProperties().NextLink,
(Int64)totalRows.Value);
}
In the above code the "tempResults" returned 20 rows and the "totalRows"
returned 100.
So PageResult received "100" as the count parameter but something under the
hood change it back to "20".
I need so way of telling SQL to return "20" rows "which my stored procedure is
already doing" and then telling the client / caller that there are more than
20 rows on the PageResult / "OData.Count".
If PageResult is modifying the overall "OData.Count" in the JSON returned to
the client, then is there some other way of for custom paging?
Original CodePlex Issue: Issue 2164
Status: Proposed
Reason Closed: Unassigned
Assigned to: Unassigned
Reported on: Oct 22, 2014 at 6:21 PM
Reported by: goroth
Updated on: Oct 22, 2014 at 10:34 PM
Updated by: danroth27
On _2014-10-23 01:35:29 UTC_, goroth commented:
Found the problem.
If I and "EnableQuery" to the function attribute then the "count" parameter does not work.
I still think the "count" parameter should return what I tell it to return even if I "EnableQuery" on my function.
On _2014-10-23 01:36:54 UTC_, goroth commented:
EDIT: added correction. changed "and" to "add"
Found the problem.
If I add "EnableQuery" to the function attribute then the "count" parameter does not work.
I still think the "count" parameter should return what I tell it to return even if I "EnableQuery" on my function.
Follow up to investigate if need to improve the implementation and updated the document. To ignore EnableQuery when there are ODataQueryOption exists.
Any fix or workaround for this? This is very annoying and time consuming
While awaiting the offical fix, I have found that creating my own EnableQuery attribute and overriding ApplyQuery to do nothing works.
// OData framework's EnableQuery attribute will apply query's again, after we have already applied the query to the result set
// (So For e.g. you will get Top and Skip applied again on your results that have already had top and skip applied
// this is a workaround the disables client side queries until this is fixed.
// https://github.com/OData/WebApi/issues/159
public class EnableCustomQueryAttribute : EnableQueryAttribute
{
public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
{
return queryable;
}
}
Most helpful comment
While awaiting the offical fix, I have found that creating my own EnableQuery attribute and overriding ApplyQuery to do nothing works.
// OData framework's EnableQuery attribute will apply query's again, after we have already applied the query to the result set // (So For e.g. you will get Top and Skip applied again on your results that have already had top and skip applied // this is a workaround the disables client side queries until this is fixed. // https://github.com/OData/WebApi/issues/159 public class EnableCustomQueryAttribute : EnableQueryAttribute { public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions) { return queryable; } }