0

I wanted to know if it was possible to filter on a specific array element. I know that it is possible to filter on nested properties and to apply any/all functions on collections, but didn't find any documentation on how to filter on specific index on collection. As an example (expressed in Linq):

data.Where(d => d.Proposals[0].Growth.Value == 0.05m)

I'm expecting a syntax like:

$filter=Proposals(0)/Growth/Value eq 0.05M

1 Answer 1

2

OData is based on the Entity Data Model, which does not support ordered collections (arrays). So there is no built-in syntax for filtering by position.

If your goal is to filter against a default Growth/Value using a client-supplied value, you can achieve that with an OData function. Declare the function in your Web API config.

// builder is an instance of ODataConventionModelBuilder
var defaultGrowthValueFunction = builder.EntityType<Zebra>().Collection.Function("WhereGrowthEquals");
defaultGrowthValueFunction.Parameter<decimal>("value");
defaultGrowthValueFunction.ReturnsCollectionFromEntitySet<Zebra>("Zebras");

The function is named WhereGrowthEquals and it is bound to the Zebras entity set. (I've invented an entity type named Zebra to host the Proposals array from your example above.)

Now define the function in the ZebrasController. (For testing, I defined a static list of Zebra instances named AllZebras.)

public class ZebrasController : ODataController
{
    [HttpGet]
    [ODataRoute("Zebras/Default.WhereGrowthEquals(value={value})")]
    public IHttpActionResult WhereGrowthEquals(decimal value)
    {
        return this.Ok(AllZebras.Where(z => z.Proposals[0].Growth.Value == value));
    }
}

Note that the bound function is namespace-qualified in the ODataRoute attribute. (Default is the default namespace name.)

Finally, invoke the function from the client as follows.

GET http://hostname/Zebras/Default.WhereGrowthEquals(value=0.05)
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your detailed answer. Actually I need to express the filter request in a generic way, I can't implement specific filtering on the server side. I mean the requests are to be generated by a client grid depending on the shown columns and those columns are a projection of complex objects (including arrays). I could have another columns referencing a path like Proposals[1].AnotherArray[2].Amount.Value. So, I'm looking for a standard and generic syntaxt to express that path in OData query.
Hmmm. I'm curious as to how you are modeling the arrays. What does your $metadata doc look like?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.