OData / WebApi

OData Web API: A server library built upon ODataLib and WebApi
https://docs.microsoft.com/odata
Other
857 stars 473 forks source link

Filter Issue with All() and no children #1061

Open mark--stephenson opened 7 years ago

mark--stephenson commented 7 years ago

I am seeing some unusual behaviour in my oData web api project when filtering.

My domain has "people", who can have non, one, or many "addresses" associated with them. For example, see below for the result of http://localhost:4839/odata/v1/people?$expand=addresses

{
    "@odata.context": "http://localhost:4839/odata/v1/$metadata#people",
    "value": [
        {
            "title": "Mr",
            "forename": "Bob",
            "surname": "Smith",
            "addresses": [
                {
                    "address_line_1": "6 High Garden",
                    "address_line_2": "HARTON",
                    "post_code": "YO6 1LZ",
                    "city": null,
                    "state_province": null,
                    "county": null,
                    "country": "UK",
                }
            ]
        },
        {
            "title": "Mrs",
            "forename": "Jane",
            "surname": "Bond",
            "addresses": [
                {
                    "address_line_1": "69 Balsham Road",
                    "address_line_2": "ALCISTON",
                    "post_code": "BN26 1BH",
                    "city": null,
                    "state_province": null,
                    "county": null,
                    "country": "UK",
                }
            ]
        },
        {
            "title": "Mr",
            "forename": "Thomas",
            "surname": "Walker",
            "addresses": [
                {
                    "address_line_1": "90 George Street",
                    "address_line_2": "BRUSHFORD BARTON",
                    "post_code": "EX18 7SX",
                    "city": null,
                    "state_province": null,
                    "county": null,
                    "country": "Spain",
                }
            ]
        },
        {
            "title": "Mr",
            "forename": "Glen",
            "surname": "Anthony",
            "addresses": []
        }
    ]
}

If I want to filter people and only return people who have all their addresses in the UK, I would expect the following query to work http://localhost:4839/odata/v1/people?$filter=addresses/all(a: a/country eq 'UK'), but this returns Bob Smith, Jane Bond and Glen Anthony. Can anyone explain why Glen Anthony is returned by this query, or is it a bug?

I'm using Microsoft.AspNet.OData v6.0.0

fenixil commented 7 years ago

Hello Mark, team, I believe that is expected behavior (at least for LINQ-to-objects) - Enumerable.All() returns true if collection is empty.

You may workaround this issue checking if addresses is not empty by adding and addresses/any() to your uri:

~/odata/v1/people?$filter=addresses/all(a: a/country eq 'UK') and addresses/any()