Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature ask: support in memory filtering after ODataQueryOptions.ApplyTo() #766

Open
xubinzheng opened this issue Dec 8, 2022 · 3 comments · May be fixed by #824
Open

Feature ask: support in memory filtering after ODataQueryOptions.ApplyTo() #766

xubinzheng opened this issue Dec 8, 2022 · 3 comments · May be fixed by #824
Labels

Comments

@xubinzheng
Copy link

I want to follow up on this very old ticket: OData/WebApi#521

This issue was raised in 2015, and the same limitation seems still exist in the Odata.ApplyTo(). I am wondering is there a better solution than You can do this to check for a $select wrapper, get a Dictionary of key,values and then map it your model. at this moment?
image

Similar to the original question, I am trying to perform in memory filtering of a query, after it has been retrieved from the downstream API, and before returning it to the client.

Using ODataQueryOptions.ApplyTo(...) I can let OData do all it's query magic on the in-memory data. However if $expand or $select has been supplied, the returned IQueryable contains not the entities themselves, but SelectExpandWrapper objects. Which it is impossible to extract the original entity from.

Ideally I would like to be able to do something like this in a controller action

public IQueryable<Entity> GetFeed(ODataQueryOptions<Entity> opts)
{
    IQueryable<Entity> result = opts.ApplyTo(<IEnumerable>.AsQueryable<Entity>())

    foreach (var item in result)
    {
        // perform extra filtering here
    }
    return result;
}

Expected result

Any suggestions will be very helpful.

@xubinzheng xubinzheng added the bug Something isn't working label Dec 8, 2022
@julealgon
Copy link
Contributor

Can't you filter the data before applying the queryoptions?

Can you elaborate a bit more on what is it exactly you are trying to do, and why you think filtering after applying the OData query options would be the way to go?

@mikepizzo mikepizzo added feature and removed bug Something isn't working labels Dec 20, 2022
@xubinzheng
Copy link
Author

@julealgon yep. Firstly the queryoptions are applied to the downstream APIs directly, like calling MSGraph with $select=Id. So the data doesn't exist in the memory for filtering before applying the queryoptions.

More specifically, in our case, this is for an evaluation purpose.

We have a legacy code path that calls some downstream APIs. And we have a new code path that calls MSGraph. Today when a request came in, we run both flows in parallel, and only return the response from the legacy flow. But before we return the response, we have the logic that compares results between the legacy and the new flow to make sure they are equivalent. That helps us smoothly switch to the new code path.

We need to cover the query results back to C# objects to apply the comparison logic.

@julealgon
Copy link
Contributor

@julealgon yep. Firstly the queryoptions are applied to the downstream APIs directly, like calling MSGraph with $select=Id. So the data doesn't exist in the memory for filtering before applying the queryoptions.

MSGraph is an OData API as well right? So you could just filter the data by appending extra filters on $filter before sending the request to them.

I'm not exactly sure how you are making that request, but I assume using a DataServiceContext would make the most sense: you could then add extra Where clauses to the context before applying the ODataQueryOptions onto it.

More specifically, in our case, this is for an evaluation purpose.

We have a legacy code path that calls some downstream APIs. And we have a new code path that calls MSGraph. Today when a request came in, we run both flows in parallel, and only return the response from the legacy flow. But before we return the response, we have the logic that compares results between the legacy and the new flow to make sure they are equivalent. That helps us smoothly switch to the new code path.

We need to cover the query results back to C# objects to apply the comparison logic.

Would it not be better if you could filter the data in the legacy API upfront as well? Or is that just not an option for some reason?

You wouldn't need to apply any filters after any of the queries run in that case: just make the 2 calls with filtering already in place, and compare the final results directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants