ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.26k stars 745 forks source link

Nested pagination does not work with projection #4424

Open madiganz opened 3 years ago

madiganz commented 3 years ago

Is there an existing issue for this?

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

vermion commented 2 years ago

Seeing this bug in Hot Chocolate 12.3.2 with EF Core 6. Any word on when this can be resolved?

FilipeDominguesGit commented 2 years ago

Same issue .NET 6 , EF Core 6 and Hot Chocolate 12.4.0-preview.14.

ThatDeveloper commented 2 years ago

Hey there. Is there an update on this? Nested pagination would be very important for us.

michaelstaib commented 2 years ago

We are working on a new projection engine for 13. We are looking at November at the moment.

Temppus commented 2 years ago

Hi, is November still expected date ? We are experiencing same issue here.

AlexandreNeKeR commented 1 year ago

Since v13.0.0, projection and pagination do not produce error on nested object but there's no projection. The SQL query only request for parent object so nested object appear as "null".