如何在Hot Chocolate(v13) GraphQL中过滤列表字段元素?
在Hot Chocolate中为现有列表字段添加
where过滤(无需新增字段) 默认情况下,Hot Chocolate为集合字段提供的any/none/all等过滤器是用来判断父对象是否满足子集合的条件,而非直接过滤子集合元素。要实现直接在B.c字段上通过isNew筛选元素的需求,你可以通过以下两种方案扩展过滤逻辑:
方案1:字段级过滤扩展(简单直接)
通过类型扩展为B.c字段添加自定义过滤参数,在解析时直接对子列表应用筛选逻辑:
1.1 定义过滤输入类型
创建针对C的过滤输入,用于接收筛选条件:
public class CFilterInput { public bool? IsNew { get; set; } }
1.2 扩展B类型的字段解析
为B的c字段添加过滤逻辑,覆盖原字段的解析行为:
[ExtendObjectType(typeof(B))] public class BFilterExtensions { [GraphQLName("c")] public IEnumerable<C> FilterCList( [Parent] B parent, [GraphQLType(typeof(CFilterInput))] CFilterInput? filter) { var cList = parent.c ?? Enumerable.Empty<C>(); // 应用isNew过滤条件 if (filter?.IsNew.HasValue == true) { cList = cList.Where(c => c.isNew == filter.IsNew.Value); } return cList; } }
1.3 注册扩展并启用过滤
在GraphQL服务配置中注册该扩展,确保过滤生效:
builder.Services .AddGraphQLServer() .AddQueryType<Query>() .AddTypeExtension<BFilterExtensions>() .AddFiltering();
1.4 编写查询
现在可以直接在查询中对c字段使用where参数:
query GetFilteredA { getA { b { name c(where: { isNew: true }) { isNew } } } }
方案2:集成原生过滤体系(更贴合Hot Chocolate生态)
通过自定义过滤操作处理器,将where过滤集成到Hot Chocolate的原生过滤系统中,支持更复杂的筛选条件:
2.1 实现集合过滤操作处理器
创建处理集合where过滤的处理器:
public class CollectionWhereFilterOperationHandler : FilterOperationHandler<QueryableFilterContext> { public override bool CanHandle( IFilterOperationDefinition definition, IFilterInputType type) { return definition.Name.Equals("where", StringComparison.OrdinalIgnoreCase) && type is IFilterInputType; } public override Expression Handle( IFilterOperationDefinition definition, IFilterInputType type, Expression value, Expression instance) { var elementType = instance.Type.GetGenericArguments()[0]; var filterContext = new QueryableFilterContext(elementType); var filterExpression = ((IFilterInputType)type).CreateFilter(filterContext, value); // 构建Queryable.Where的调用表达式 return Expression.Call( typeof(Queryable), "Where", new[] { elementType }, instance, filterExpression); } }
2.2 注册处理器
在过滤配置中添加自定义处理器:
builder.Services .AddGraphQLServer() .AddQueryType<Query>() .AddFiltering(options => { options.AddOperationHandler<CollectionWhereFilterOperationHandler>(); });
2.3 编写查询
此时可以使用Hot Chocolate原生的过滤语法来筛选子列表:
query GetFilteredA { getA { b { name c(where: { isNew: { eq: true } }) { isNew } } } }
内容的提问来源于stack exchange,提问作者Tamar
相关产品推荐
相关产品推荐

