Skip to content

Nested pagination does not work with projection #4424

@madiganz

Description

@madiganz

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I am using HotChocolate 12.2.0 with Entity Framework 5.0.10 and when trying to add nested pagination to a query with projection, an error is thrown. I expect no error to be thrown and the nested data to be retrieved by the query and also be able to be paged.

Have also tried adding ResolveWith to the Assets field and the same error is thrown.

Steps to reproduce

public record Account
{
    public string Name { get; set; } = null!;
    public ICollection<Asset> Assets { get; set; } = new List<Asset>();
}

public record Asset
{
    public string Name { get; set; } = null!;
}

public class AccountType : ObjectType<Account>
{
    protected override void Configure(IObjectTypeDescriptor<Account> descriptor)
    {
        descriptor
            .Field(d => d.Name)
            .Description("Name of the account.");

        descriptor
            .Field(d => d.Assets)
            .UsePaging()
            .UseProjection()
            .UseFiltering()
            .UseSorting();
    }
}

public class AssetType : ObjectType<Asset>
{
    protected override void Configure(IObjectTypeDescriptor<Asset> descriptor)
    {
        descriptor
            .Field(d => d.Name)
            .Description("Name of the asset.");
    }
}

public class AccountResolver
{
    public IEnumerable<Account> GetAccounts([Service] IRepositoryBase<Account> accountRepo)
    {
        return accountRepo.GetAll();
    }
}

public class AssetResolver
{
    public IEnumerable<Asset> GetAssets([Service] IRepositoryBase<Asset> assetRepo)
    {
        return assetRepo.GetAll();
    }
}

public class Query : ObjectType
{
    protected override void Configure(IObjectTypeDescriptor descriptor)
    {
        descriptor
            .Field("accounts")
            .ResolveWith<AccountResolver>(d => d.GetAccounts(default!))
            .UsePaging()
            .UseProjection()
            .UseFiltering()
            .UseSorting();

        descriptor
            .Field("assets")
            .ResolveWith<AssetResolver>(d => d.GetAssets(default!))
            .UsePaging()
            .UseProjection()
            .UseFiltering()
            .UseSorting();
    }
}

The Repositories are simple wrappers over the Entity Framework DbSet for that type

Relevant log output

"message": "Type 'System.Collections.Generic.ICollection`1[Asset]' does not have a default constructor (Parameter 'type')",

"stackTrace": "   at System.Linq.Expressions.Expression.New(Type type)\r\n   at HotChocolate.Data.Projections.Expressions.QueryableProjectionScopeExtensions.CreateMemberInit(QueryableProjectionScope scope)\r\n   at HotChocolate.Data.Projections.Expressions.Handlers.QueryableProjectionFieldHandler.TryHandleLeave(QueryableProjectionContext context, ISelection selection, ISelectionVisitorAction& action)\r\n   at HotChocolate.Data.Projections.Expressions.Handlers.ProjectionFieldWrapper`1.TryHandleLeave(T context, ISelection selection, ISelectionVisitorAction& action)\r\n   at HotChocolate.Data.Projections.ProjectionVisitor`1.Leave(ISelection selection, TContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.Visit(ISelection selection, TContext context)\r\n   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(ISelection selection, TContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitObjectType(IOutputField field, ObjectType objectType, SelectionSetNode selectionSet, TContext context)\r\n   at HotChocolate.Data.Projections.Expressions.QueryableProjectionVisitor.VisitObjectType(IOutputField field, ObjectType objectType, SelectionSetNode selectionSet, QueryableProjectionContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitChildren(IOutputField field, TContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.Visit(IOutputField field, TContext context)\r\n   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(IOutputField field, TContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitChildren(ISelection selection, TContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.Visit(ISelection selection, TContext context)\r\n   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(ISelection selection, TContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitObjectType(IOutputField field, ObjectType objectType, SelectionSetNode selectionSet, TContext context)\r\n   at HotChocolate.Data.Projections.Expressions.QueryableProjectionVisitor.VisitObjectType(IOutputField field, ObjectType objectType, SelectionSetNode selectionSet, QueryableProjectionContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.VisitChildren(IOutputField field, TContext context)\r\n   at HotChocolate.Data.Projections.SelectionVisitor`1.Visit(IOutputField field, TContext context)\r\n   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(IOutputField field, TContext context)\r\n   at HotChocolate.Data.Projections.ProjectionVisitor`1.Visit(TContext context)\r\n   at HotChocolate.Data.Projections.Expressions.QueryableProjectionProvider.<>c__5`1.<CreateApplicatorAsync>b__5_0(IResolverContext context, Object input)\r\n   at HotChocolate.Data.Projections.Expressions.QueryableProjectionProvider.<>c__DisplayClass4_0`1.<<CreateExecutor>g__ExecuteAsync|1>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n   at HotChocolate.Types.Pagination.PagingMiddleware.InvokeAsync(IMiddlewareContext context)\r\n   at HotChocolate.Utilities.MiddlewareCompiler`1.ExpressionHelper.AwaitTaskHelper(Task task)\r\n   at HotChocolate.AspNetCore.Authorization.AuthorizeMiddleware.InvokeAsync(IDirectiveContext context)\r\n   at HotChocolate.Utilities.MiddlewareCompiler`1.ExpressionHelper.AwaitTaskHelper(Task task)\r\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\r\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)"

Additional Context?

No response

Product

Hot Chocolate

Version

12.2.0

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions