简体   繁体   English

如何覆盖 HotChocolate 生成的过滤链接查询?

[英]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.我有一个案例,我需要在过滤查询中向 graphql 服务器发送数万个 id。

the query now generated by the HT is something like this:现在由 HT 生成的查询是这样的:

_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我有两个问题: 1-性能低下 2-SQL Server 限制我猜是 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:我找到了一个 Nuget 库来将这个静态列表转换为临时表,所以现在我想重写 HT 中间以将上面生成的查询重写为以下内容:

_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.这将为这个静态 ID 列表创建一个临时表,这样我就能够解决我遇到的上述两个问题。

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 :因此,由于我没有得到答案,我不得不向 HotChocolate 团队的 Slack 询问,希望他们为我提供了文档extending-filtering/extending-iqueryable

in case the link was broken, here is如果链接断开,这里是

Extending IQueryable The default filtering implementation uses IQueryable under the hood.扩展 IQueryable默认的过滤实现在底层使用 IQueryable。 You can customize the translation of queries by registering handlers on the QueryableFilterProvider.您可以通过在 QueryableFilterProvider 上注册处理程序来自定义查询的翻译。

The following example creates a StringOperationHandler that supports case-insensitive filtering:以下示例创建一个支持不区分大小写过滤的 StringOperationHandler:

 // 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.为了使注册更容易,Hot Chocolate 还支持约定和提供商扩展。 Instead of creating a custom FilterConvention, you can also do the following:除了创建自定义 FilterConvention,您还可以执行以下操作:

 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.但有人建议我这样做(向 graphQL 服务器发送多达 100k 的字符串 ID 列表)不是一个好方法。 so I decided to take another approach by writing a custom simple dynamic LINQ generates.所以我决定采用另一种方法,编写一个自定义的简单动态 LINQ 生成器。

Thanks.谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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