OData / AspNetCoreOData

ASP.NET Core OData: A server library built upon ODataLib and ASP.NET Core
Other
458 stars 158 forks source link

CosmosSDK with ODataQueryOptions breaks when using $select #1062

Open Supernectar opened 1 year ago

Supernectar commented 1 year ago

Assemblies affected ASP.NET Core OData 8.2.3 and Microsoft.Azure.Cosmos 3.35.4

Describe the bug Using the ODataQueryOptions.ApplyTo Method with the Container.GetItemLinqQueryable Method throws an exception only, and only if the user provides a $select option in the url. Any other option such as $top, $skip, $filter work fine. Only when using $select the exception is thrown.

Reproduce steps

  1. Clone this repo https://github.com/Supernectar/ODataCosmosDBSelectBug.git

  2. Run the web app

  3. Make a GET request to any of these urls:

  4. See the exception being returned image

NOTE: You need to have a cosmosDB emulator running with a database named "TestDB" and a container named "test". Ideally this container should contain some sample data:

{
    "id": "c1429a3e-146c-4df7-8b9e-7c634b19f1a1",
    "name": "John Doe",
    "orders": [
        {
            "id": "f0c26d64-7e11-4ed1-8211-efae44f7f57d",
            "amount": 50.25,
            "type": 0
        },
        {
            "id": "5b4e0849-6b5c-4f75-9e75-86b48cb58353",
            "amount": 75.5,
            "type": 1
        }
    ]
}
{
    "id": "9e1a50a2-8e21-4f70-8f0a-ebbdac2b5e0f",
    "name": "Jane Smith",
    "orders": [
        {
            "id": "7273848c-f662-4e6b-b9ed-cd47d3d5e3fc",
            "amount": 30.75,
            "type": 1
        }
    ]
}
{
    "id": "ecb4e60f-5a82-4f10-aae0-06c3e8b21fe0",
    "name": "Bob Johnson",
    "orders": []
}

Data Model This is the main class where the exception is being generated:

public class CosmosService : ICosmosService
{
    private readonly CosmosClient _cosmosClient;

    public CosmosService(CosmosClient cosmosClient)
    {
        _cosmosClient = cosmosClient;

    }

    private Container Container
    {
        get => _cosmosClient.GetContainer("TestDB", "test");
    }

    public async Task<IEnumerable<Customer>> GetCustomers(ODataQueryOptions<Customer> queryOptions)
    {
        var customerList = new List<Customer>();

        var customerQueryable = Container.GetItemLinqQueryable<Customer>();

        ODataQuerySettings querySettings = new();

        customerQueryable = queryOptions.ApplyTo(customerQueryable, querySettings) as IOrderedQueryable<Customer>;

        using FeedIterator<Customer> setIterator = customerQueryable.ToFeedIterator();

        while (setIterator.HasMoreResults)
        {
            var result = await setIterator.ReadNextAsync();
            customerList.AddRange(result.Resource);
        }

        return customerList;
    }
}

You can check the rest of the code more in details in this example repo https://github.com/Supernectar/ODataCosmosDBSelectBug.git

Request/Response When doing a GET request to any of these urls

Expected behavior I want to be able to use the $select option properly. Given the example data provided above, if I do a GET request to this url https://localhost:7234/customers?$select=orders/amount I want to receive the following data in the response body:

{
    "@odata.context": "https://localhost:7234/$metadata#Customers",
    "value": [
        {
            "Orders": [
                {
                    "Amount": 50.25
                },
                {
                    "Amount": 75.5
                }
            ]
        },
        {
            "Orders": [
                {
                    "Amount": 30.75
                }
            ]
        },
        {
            "Orders": []
        }
    ]
}
julealgon commented 1 year ago

Is this in any way related to:

?

ElizabethOkerio commented 1 year ago

This seems to be related to this: https://github.com/OData/AspNetCoreOData/issues/1056 too. There is an open issue in the Cosmos SDK repo https://github.com/Azure/azure-cosmos-dotnet-v3/issues/4096 that we are currently following up with.

CSharpFiasco commented 3 months ago

Is there a status update on this? This would be very useful to be fixed