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

fix $orderby with $apply and groupby aggregations #919

Merged

Conversation

ElizabethOkerio
Copy link
Contributor

@ElizabethOkerio ElizabethOkerio commented May 15, 2023

This PR fixes these issues: #889, #420

Executing a query like this: https://localhost:7098/odata/Customers?$apply=groupby((Name),aggregate(Amount with sum as TotalAmount))&$orderby=Name in AspNetCore OData greater than 8.0.4 and EfCore throws an exception.

@ElizabethOkerio ElizabethOkerio changed the title fix $orderby with $apply and group by aggregations fix $orderby with $apply and groupby aggregations May 15, 2023
@ElizabethOkerio ElizabethOkerio merged commit d615834 into OData:main May 16, 2023
2 checks passed
@orty
Copy link
Contributor

orty commented May 16, 2023

Great ! 👍
Looking forward to trying this fix

@kairgrw
Copy link

kairgrw commented May 18, 2023

@ElizabethOkerio Thanks.
But this fix only works for apply with groupBy and still doesn't without it.
The 4th request in #918 still fails.

Can this fix be later merged to 8.0.12? Or we should wait for the next release?
I see it was only merged to main.

@ElizabethOkerio
Copy link
Contributor Author

@kairgrw yes working on a fix for #918. The change for apply with groupby will be in the next release.

@REP2AV
Copy link

REP2AV commented May 30, 2023

This still fails if the group by has more that one property. It works on version 8.0.4

For example:
https://localhost:7098/odata/Customers?$apply=groupby((Name,LastName),aggregate(Amount with sum as TotalAmount))&$orderby=Name

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.ArgumentException: Method 'System.Object get_Item(System.String)' declared on type 'System.Collections.Generic.Dictionary2[System.String,System.Object]' cannot be called with instance of type 'System.Object' at System.Linq.Expressions.Expression.ValidateCallInstanceType(Type instanceType, MethodInfo method) at System.Linq.Expressions.Expression.ValidateAccessor(Expression instance, MethodInfo method, ParameterInfo[] indexes, ReadOnlyCollection1& arguments, String paramName)
at System.Linq.Expressions.Expression.ValidateIndexedProperty(Expression instance, PropertyInfo indexer, String paramName, ReadOnlyCollection1& argList) at System.Linq.Expressions.Expression.MakeIndex(Expression instance, PropertyInfo indexer, IEnumerable1 arguments)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateThenBy(ShapedQueryExpression source, LambdaExpression keySelector, Boolean ascending)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_01.<Execute>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at Microsoft.AspNetCore.OData.Query.Container.TruncatedCollection1..ctor(IQueryable1 source, Int32 pageSize, Boolean parameterize) at Microsoft.AspNetCore.OData.Query.ODataQueryOptions.LimitResults[T](IQueryable1 queryable, Int32 limit, Boolean parameterize, Boolean& resultsLimited)
at InvokeStub_ODataQueryOptions.LimitResults(Object, Object, IntPtr*)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
--- End of inner exception stack trace ---

@ElizabethOkerio
Copy link
Contributor Author

ElizabethOkerio commented May 30, 2023

@REP2AV just tried this https://localhost:7098/odata/Customers?$apply=groupby((Name,LastName),aggregate(Amount%20with%20sum%20as%20TotalAmount))&$orderby=Name and it works. Are you using v8.2.0? can you share a repro?

This will fail if you try to do $orderby on a property that is not an output of the group-by transformation. This is not supported. check this comment: #420 (comment)

@REP2AV
Copy link

REP2AV commented May 30, 2023

@ElizabethOkerio Yes, using 8.2.0.

I've creted this repo with a minimal working example.

/api/v2/WeatherForecasts?$apply=groupby((TemperatureC),aggregate($count as Count))&$orderby=TemperatureC -> works
/api/v2/WeatherForecasts?$apply=groupby((Summary),aggregate($count as Count))&$orderby=Summary-> works
/api/v2/WeatherForecasts?$apply=groupby((TemperatureC,Summary),aggregate($count as Count))&$orderby=TemperatureC -> fails

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

Successfully merging this pull request may close these issues.

None yet

5 participants