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

Problem when $apply is combined with other query options like $filter and $orderby #939

Closed
imoraca opened this issue May 25, 2023 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@imoraca
Copy link

imoraca commented May 25, 2023

Assemblies affected
Microsoft.AspNetCore.OData v 8.2.0 (Problem persists since v 8.0.5)

Describe the bug
When $apply is combined with $filter or $orderby an error occurs. $apply should be evaluated first, so all dynamic properties introduced in the $apply should be available for later query options. However this doesn't seem to work.

Example

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as TotalAmount))&$filter=TotalAmount gt 23

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as TotalAmount))/filter(TotalAmount gt 23)

In both cases I receive the following error:
The binary operator GreaterThan is not defined for the types 'System.Object' and 'System.Nullable`1[System.Decimal]'

When I try to combine $apply and $order I also get an error:

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as Total))&$orderby=Total desc

This time the error is:
Could not find a property named 'Total' on type 'AggregationSample.Models.Order'

Data Model

    public class Order
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public decimal TotalAmount { get; set; }
        public Customer Customer { get; set; }
    }
    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public IList<string> Emails { get; set; }
        public Address HomeAddress { get; set; }
        public IList<Address> FavoriteAddresses { get; set; }
        public Order PersonOrder { get; set; }
        public IList<Order> Orders { get; set; }
    }

EDM (CSDL) Model

        public static IEdmModel GetEdmModel()
        {
            var builder = new ODataConventionModelBuilder();
            builder.EntitySet<Customer>("Customers");
            builder.EntitySet<Order>("Orders");
            builder.EntitySet<ZipCode>("ZipCodes");
            return builder.GetEdmModel();
        }
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema Namespace="AggregationSample.Models" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="Customer">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="Name" Type="Edm.String" />
                <Property Name="Emails" Type="Collection(Edm.String)" />
                <Property Name="HomeAddress" Type="AggregationSample.Models.Address" />
                <Property Name="FavoriteAddresses" Type="Collection(AggregationSample.Models.Address)" />
                <NavigationProperty Name="PersonOrder" Type="AggregationSample.Models.Order" />
                <NavigationProperty Name="Orders" Type="Collection(AggregationSample.Models.Order)" />
            </EntityType>
            <EntityType Name="Order">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="Title" Type="Edm.String" />
                <Property Name="TotalAmount" Type="Edm.Decimal" Nullable="false" Scale="Variable" />
                <NavigationProperty Name="Customer" Type="AggregationSample.Models.Customer" />
            </EntityType>
            <EntityType Name="ZipCode">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="DisplayName" Type="Edm.String" />
            </EntityType>
            <ComplexType Name="Address">
                <Property Name="Street" Type="Edm.String" />
                <Property Name="City" Type="Edm.String" />
                <NavigationProperty Name="ZipCode" Type="AggregationSample.Models.ZipCode" />
            </ComplexType>
            <ComplexType Name="BillAddress" BaseType="AggregationSample.Models.Address">
                <Property Name="FirstName" Type="Edm.String" />
                <Property Name="LastName" Type="Edm.String" />
            </ComplexType>
        </Schema>
        <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityContainer Name="Container">
                <EntitySet Name="Customers" EntityType="AggregationSample.Models.Customer">
                    <NavigationPropertyBinding Path="FavoriteAddresses/ZipCode" Target="ZipCodes" />
                    <NavigationPropertyBinding Path="HomeAddress/ZipCode" Target="ZipCodes" />
                    <NavigationPropertyBinding Path="Orders" Target="Orders" />
                    <NavigationPropertyBinding Path="PersonOrder" Target="Orders" />
                </EntitySet>
                <EntitySet Name="Orders" EntityType="AggregationSample.Models.Order">
                    <NavigationPropertyBinding Path="Customer" Target="Customers" />
                </EntitySet>
                <EntitySet Name="ZipCodes" EntityType="AggregationSample.Models.ZipCode" />
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

These queries use to work prior to ver. 8.0.5. Is there any workaround for this and will it be fixed in future versions?

@imoraca imoraca added the bug Something isn't working label May 25, 2023
@ElizabethOkerio
Copy link
Contributor

ElizabethOkerio commented May 26, 2023

@imoraca This issue was fixed by this PR: #919. We'll do a new release soon with the changes.

You can also look at this answer in regards to the introduced dynamic properties: #420 (comment)

@imoraca
Copy link
Author

imoraca commented May 26, 2023

@ElizabethOkerio I'm a little bit confused about the next release.

Using VS2022 I've downloaded Microsoft.AspNetCore.OData using Nuget Manager (Package source: nuget.org) and as I can see the latest stable version is 8.2.0

But, here on GitHub, the latest release is 8.1.2

How come nuget.org has version 8.2.0 while here on github the latest stable release is 8.1.2

Why isn't this synchronized and what will be the number of the next release?

@ElizabethOkerio
Copy link
Contributor

@imoraca we've synchronized the GitHub release with the nuget release.

@imoraca
Copy link
Author

imoraca commented May 30, 2023

Version 8.2.0 is still giving the same error. It looks like that dynamic properties introduced in the $apply are not available for later query options. (Look at my original comment).

Examples that reproduce the error:

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as TotalAmount))&$filter=TotalAmount gt 23

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as TotalAmount))/filter(TotalAmount gt 23)

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as Total))&$orderby=Total desc

Will this be fixed in future versions?

@ElizabethOkerio
Copy link
Contributor

ElizabethOkerio commented May 30, 2023

The fix for $apply with $filter will be in future versions. You can test with the main branch though and see whether the issue still persists. For the dynamic properties, did you look at this comment? #420 (comment). If you do a groupby transformation in $apply that doesn't include a property from your input data set, that property is not available for subsequent transformations or other query options (such as $orderby).

@imoraca
Copy link
Author

imoraca commented May 30, 2023

@ElizabethOkerio Yes, I've looked at comment #420 (comment) and I totally agree. In my example groupby transformation in $apply includes a property from the input data set, but that property is still not available for subsequent transformations or other query options.

Examples:

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as TotalAmount))&$filter=TotalAmount gt 23

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as TotalAmount))/filter(TotalAmount gt 23)

http://localhost:5000/odata/Orders?$apply=groupby((Customer/Name), aggregate($count as OrderCount, TotalAmount with sum as Total))&$orderby=Total desc

This is still an issue with version 8.2.0

Can this issue be reopened or should I open the new one?

@ElizabethOkerio
Copy link
Contributor

Create a new issue for better tracking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants