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 746 forks source link

QueryableOffsetPagingProvider.cs CanHandle -> NotImplementedException #5082

Open cphillips83 opened 2 years ago

cphillips83 commented 2 years ago

Is there an existing issue for this?

Describe the bug

The documentation for 12.9.0 shows MongoDb has several AddMongoDbXYZ methods to register things like filtering, sorting, pagination, etc but I'm not able to find the equivalent for Entity Framework. When trying to use OffsetPagingProvider you get a NotImplemenetException which can be found here in CanHandle while the MongoDb version appears to have a proper implementation.

Steps to reproduce

builder.Services
    .AddGraphQLServer()
    .RegisterDbContext<ApplicationDbContext>()
    .AddFiltering()
    .AddSorting()
    .AddProjections()
    .AddQueryableOffsetPagingProvider() //NotImplemented
    .SetPagingOptions(new HotChocolate.Types.Pagination.PagingOptions { MaxPageSize = 100 })
    .AddQueryType<Query>();

Relevant log output

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.NotImplementedException: The method or operation is not implemented.
         at HotChocolate.Types.Pagination.QueryableOffsetPagingProvider.CanHandle(IExtendedType source)
         at HotChocolate.Types.OffsetPagingObjectFieldDescriptorExtensions.<>c__DisplayClass7_0.<ResolvePagingProvider>b__0(PagingProviderEntry entry)
         at HotChocolate.Types.OffsetPagingObjectFieldDescriptorExtensions.ResolvePagingProvider(IServiceProvider services, IExtendedType source, String providerName)
         at HotChocolate.Types.OffsetPagingObjectFieldDescriptorExtensions.<>c__DisplayClass1_0.<UseOffsetPaging>b__0(IServiceProvider services, IExtendedType source, String name)
         at HotChocolate.Types.Pagination.PagingHelper.ApplyConfiguration(ITypeCompletionContext context, ObjectFieldDefinition definition, Type entityType, String name, GetPagingProvider resolvePagingProvider, PagingOptions options, FieldMiddlewareDefinition placeholder)
         at HotChocolate.Types.Pagination.PagingHelper.<>c__DisplayClass0_0.<UsePaging>b__1(ITypeCompletionContext c, ObjectFieldDefinition d)
         at HotChocolate.Types.Descriptors.Definitions.CompleteConfiguration`1.<>c__DisplayClass0_0.<.ctor>b__0(ITypeCompletionContext c, IDefinition d)
         at HotChocolate.Types.TypeSystemObjectBase`1.ExecuteConfigurations(ITypeCompletionContext context, TDefinition definition, ApplyConfigurationOn on)
         at HotChocolate.Types.TypeSystemObjectBase`1.CompleteType(ITypeCompletionContext context)
         at HotChocolate.Configuration.TypeInitializer.<CompleteTypes>g__CompleteType|27_0(RegisteredType registeredType)
         at HotChocolate.Configuration.TypeInitializer.ProcessTypes(TypeDependencyKind kind, Func`2 action)
         at HotChocolate.Configuration.TypeInitializer.CompleteTypes()
         at HotChocolate.Configuration.TypeInitializer.Initialize()
         at HotChocolate.SchemaBuilder.Setup.InitializeTypes(SchemaBuilder builder, IDescriptorContext context, IReadOnlyList`1 types, LazySchema lazySchema)
         at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilder builder, LazySchema lazySchema, IDescriptorContext context)
         at HotChocolate.SchemaBuilder.Create(IDescriptorContext context)
         at HotChocolate.SchemaBuilder.HotChocolate.ISchemaBuilder.Create(IDescriptorContext context)
         at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(NameString schemaName, RequestExecutorSetup options, RequestExecutorOptions executorOptions, IServiceProvider serviceProvider, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
         at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(NameString schemaName, RequestExecutorSetup options, CancellationToken cancellationToken)
         at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorNoLockAsync(NameString schemaName, CancellationToken cancellationToken)
         at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorAsync(NameString schemaName, CancellationToken cancellationToken)
         at HotChocolate.Execution.RequestExecutorProxy.GetRequestExecutorAsync(CancellationToken cancellationToken)
         at HotChocolate.AspNetCore.HttpPostMiddlewareBase.HandleRequestAsync(HttpContext context, AllowedContentType contentType)
         at HotChocolate.AspNetCore.HttpPostMiddlewareBase.InvokeAsync(HttpContext context)
         at Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.<>c__DisplayClass13_0.<<UseCancellation>b__1>d.MoveNext()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Additional Context?

The documentation doesn't appear to be fully complete like MongoDb, how can we achieve the old paging, fitlering, sorting and projection with EFC in v11?

    public class Query
    {
        [UseOffsetPaging]
        [UseProjection]
        [UseFiltering]
        [UseSorting]
        public IExecutable<User> GetUser(ApplicationDbContext dbContext) => dbContext.Users.AsExecutable();
    }

Product

Hot Chocolate

Version

12.9.0

PascalSenn commented 2 years ago

EF works out of the box as it operates on IQueryable, so you do not have to register anything. Still weird that this code is in there. @michaelstaib do you remember if there is a reason for it?

huysentruitw commented 1 year ago

I see that QueryableOffsetPagingProvider is still throwing a NotImplementedException while I could make offset-paging work by inheriting from that provider and implement the CanHandle like this:

public sealed class MyOffsetProvider : QueryableOffsetPagingProvider
{
    public override bool CanHandle(IExtendedType source)
        => source.Type.IsAssignableTo(typeof(IExecutable));
}

is there a reason for this NotImplementedException?

If not, and above source type check is OK, I can transform it into a PR 😎

huysentruitw commented 9 months ago

ping 😇