'How to implement offset based pagination for nested collection in HotChocolate GraphQL?

I've been trying to add Offset pagination for a collection inside an entity. I understood that I cannot use the [UseOffsetPaging] attribute directly. So I tried implementing a type extension method to do it.

This is how the classes looks like:

Entity :

public class Person
{
   public int Id { get; set; }
   public string Name { get; set; }
   public ICollection<Address> Address { get; set; }
}

public class Address
{
   public int AddressId { get; set; }
   public string HouseNumber { get; set; }
   public string City { get; set; }
   public string State { get; set; }
   public string ZipCode { get; set; }
}

Extended Type:

[ExtendObjectType(typeof(Person))]
    public class PersonType
    {
        [BindMember(nameof(Person.Address))]
        [UseOffsetPaging]
        [UseProjection]
        [UseFiltering]
        [UseSorting]
        public IQueryable<Address> GetAddresses(
            [Parent] Person person)
        {
            return person.Addresses.AsQueryable();
        }
    }

Startup.cs :

services.AddGraphQLServer()
        .AddTypeExtension<PersonType>()
        .AddQueryType<Query>()
        // omitted code for brevity

The issue I'm facing is I get two error messages, each of them in two scenarios:

  1. When I give the where,skip and take block in my GraphQL Query:

    Query:

    query
    {
      person
      {
        id,
        name,
        addresses(
         where: { // omitted code for brevity }
         skip: 0,
         take: 5
        )
        {
          houseNumber,
          city,
          state,
          zipCode
        }
      }
    }
    

Exception:

No generic method 'Where' on type 'System.Linq.Enumerable' is compatible with the 
supplied type arguments and arguments. No type arguments should be provided if the 
method is non-generic.
  1. When I remove all filters and pagination parameters from the query, but retains the attributes added on the resolver method except [BindMember]:

    Query:

    query
    {
      person
      {
        id,
        name,
        addresses{
          houseNumber,
          city,
          state,
          zipCode
        }
      }
    }
    

Exception:

Type 'System.Collections.Generic.ICollection`1[Address]' does not have a default
constructor (Parameter 'type')

If I comment out all the parameters except [BindMember], the code works and gives me the result, but that's no good for me. When I add the attributes, the extension method doesn't even hit. I also tried specifying the cursor-pagination [UsePaging] attribute directly like:

public class Person
{
   public int Id { get; set; }
   public string Name { get; set; }

   [UsePaging]
   [UseFiltering]
   public ICollection<Address> Address { get; set; }
}

but this too gives the same error and doesn't work. How can I implement pagination for Addresses collection through the Person query itself? I need to implement load-on-demand in the frontend so I need to paginate the addresses in the person query itself. Adding an additional resolver would create a delay in execution. Am I doing something wrong? If then please correct it and give me a working solution. I've been looking into this for days and I'm still not able to figure out the issue and find a fix. So if anyone knows how to fix it, please help me.

Thanks and Regards,

Arjun



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source