Skip to content

Sorting on navigation properties in EF projection with UseSorting middleware fails #8407

@drapka

Description

@drapka

Product

Hot Chocolate

Version

15.1.7

Link to minimal reproduction

https://github.com/drapka/HotChocolateGraphQlSortingBug

Steps to reproduce

  1. Run the app
  2. Run the following query:
{
  parents(order: [{ id: ASC }]) {
    id
    children { id }
  }
}
  1. Observe the error returned

What is expected?

The query should succeed with the specified ordering applied.

What is actually happening?

An excetion is thrown.

Relevant log output

{
  "errors": [
    {
      "message": "Unexpected Execution Error",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "parents"
      ],
      "extensions": {
        "message": "No generic method 'ThenBy' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. ",
        "stackTrace": "   at System.Linq.Expressions.Expression.FindMethod(Type type, String methodName, Type[] typeArgs, Expression[] args, BindingFlags flags)\n   at System.Linq.Expressions.Expression.Call(Type type, String methodName, Type[] typeArguments, Expression[] arguments)\n   at HotChocolate.Data.Sorting.Expressions.QueryableAscendingSortOperationHandler.AscendingSortOperation.CompileThenBy(Expression expression)\n   at HotChocolate.Data.Sorting.Expressions.QueryableSortVisitorContextExtensions.Compile(QueryableSortContext context, Expression source)\n   at HotChocolate.Data.Sorting.Expressions.QueryableSortVisitorContextExtensions.Sort[TSource](QueryableSortContext context, IQueryable`1 source)\n   at HotChocolate.Data.Sorting.Expressions.QueryableSortProvider.<>c__DisplayClass16_1`1.<CreateApplicatorAsync>b__1(IQueryable`1 q)\n   at HotChocolate.Data.Sorting.Expressions.QueryableSortProvider.ApplyToResult[TEntityType](Object input, Func`2 sort)\n   at HotChocolate.Data.Sorting.Expressions.QueryableSortProvider.<>c__DisplayClass16_0`1.<CreateApplicatorAsync>b__0(IResolverContext context, Object input)\n   at HotChocolate.Data.Sorting.Expressions.QueryableSortProvider.QueryableQueryBuilder.Apply(IMiddlewareContext context)\n   at HotChocolate.Types.UnwrapFieldMiddlewareHelper.<>c__DisplayClass0_1.<<CreateDataMiddleware>b__1>d.MoveNext()\n--- End of stack trace from previous location ---\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)"
      }
    }
  ],
  "data": null
}

Additional context

The issue lies in the specified sub collection ordering in the query:

    [UseSorting]
    public IQueryable<Parent> GetParents(DemoDbContext db) =>
        // Notice: NO root OrderBy applied here!
        // The navigation property is ordered
        db.Parents
            .Select(p => new Parent
            {
                Id = p.Id,
                Children = p.Children
                    .AsQueryable()
                    .OrderBy(c => c.SomeDate)
                    .ToList()
            });

The culprit that causes the error is the OrderingMethodFinder class that determines that the ordering has already been applied in the root collection:

        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            var name = node.Method.Name;

            if (node.Method.DeclaringType == typeof(Queryable) && (
                name.StartsWith(nameof(Queryable.OrderBy), StringComparison.Ordinal) ||
                name.StartsWith(nameof(Queryable.ThenBy), StringComparison.Ordinal)))
            {
                _orderingMethodFound = true;
            }

            return base.VisitMethodCall(node);
        }

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions