简体   繁体   中英

How to override the filtering link query generated by HotChocolate?

I have a case where I need to send tens of thousands of ids to the graphql server in the filtering query.

the query now generated by the HT is something like this:

_dbContext.
  Forms
  .Where(c=>staticLiistOfIds.Contains(c.Id))
  .Select(c=>new {C.Name,C.Age});

I have two problems with this: 1-slow performance 2-SQL Server Limit I guess is around 32K

I have found a Nuget library to convert this static list to a temp table,so now I want to override the HT middle to rewrite the above query generated to the following:

_dbContext.
  Forms
  .Where(c=>_dbContext..AsQueryableValues(staticLiistOfIds).Contains(c.Id))
  .Select(c=>new {C.Name,C.Age});

this will create a temp table for this static list of ids so I will be able to solve the above two problems that I have.

Thank you very much for your answer.

So since i didn't get answers, I had to ask from the Slack of HotChocolate's Team and hopefully, they provided me with the documentation extending-filtering/extending-iqueryable :

in case the link was broken, here is

Extending IQueryable The default filtering implementation uses IQueryable under the hood. You can customize the translation of queries by registering handlers on the QueryableFilterProvider.

The following example creates a StringOperationHandler that supports case-insensitive filtering:

 // The QueryableStringOperationHandler already has an implemenation of CanHandle // It checks if the field is declared in a string operation type and also checks if // the operation of this field uses the `Operation` specified in the override property further // below public class QueryableStringInvariantEqualsHandler: QueryableStringOperationHandler { // For creating a expression tree we need the `MethodInfo` of the `ToLower` method of string private static readonly MethodInfo _toLower = typeof(string).GetMethods().Single( x => x.Name == nameof(string.ToLower) && x.GetParameters().Length == 0); // This is used to match the handler to all `eq` fields protected override int Operation => DefaultFilterOperations.Equals; public override Expression HandleOperation( QueryableFilterContext context, IFilterOperationField field, IValueNode value, object parsedValue) { // We get the instance of the context. This is the expression path to the propert // eg ~> y.Street Expression property = context.GetInstance(); // the parsed value is what was specified in the query // eg ~> eq: "221B Baker Street" if (parsedValue is string str) { // Creates and returnes the operation // eg ~> y.Street.ToLower() == "221b baker street" return Expression.Equal( Expression.Call(property, _toLower), Expression.Constant(str.ToLower())); } // Something went wrong throw new InvalidOperationException(); } }

This operation handler can be registered on the convention:

 public class CustomFilteringConvention: FilterConvention { protected override void Configure(IFilterConventionDescriptor descriptor) { descriptor.AddDefaults(); descriptor.Provider( new QueryableFilterProvider( x => x.AddDefaultFieldHandlers().AddFieldHandler<QueryableStringInvariantEqualsHandler>())); } } // and then services.AddGraphQLServer().AddFiltering<CustomFilteringConvention>();

To make this registration easier, Hot Chocolate also supports convention and provider extensions. Instead of creating a custom FilterConvention, you can also do the following:

 services.AddGraphQLServer().AddFiltering().AddConvention<IFilterConvention>( new FilterConventionExtension( x => x.AddProviderExtension( new QueryableFilterProviderExtension( y => y.AddFieldHandler<QueryableStringInvariantEqualsHandler>()))));

but I was suggested that doing this way(sending up to 100k list of string ids to the graphQL server) is not a good approach. so I decided to take another approach by writing a custom simple dynamic LINQ generates.

Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM