HotChocolate中UseSorting对计算字段fullName不生效问题求助
你遇到的问题是因为HotChocolate默认的UseSorting只支持实体本身的原生字段,而fullName是你通过ResolveWith定义的运行时计算字段,不属于实体的数据库映射字段,所以排序输入对象里默认不会包含这个字段,才会报“The specified input object field fullName does not exist.”的错误。
下面分两种情况给出解决办法:
一、直接升级到HotChocolate 13+版本
既然官方已经在13+版本修复了这个问题,升级是最省心的方案。升级后,框架会自动识别你通过ResolveWith定义的计算字段,并把它加入到排序输入对象中,你现有的代码和查询语句不需要做任何修改就能正常按fullName排序。
二、低版本(<13)手动配置排序逻辑
如果暂时没法升级版本,就需要手动给排序输入对象添加fullName字段,并自己实现排序逻辑:
1. 自定义排序输入类型
创建一个继承自SortInputType<Item>的类,手动把fullName加入到排序字段列表里:
public class ItemSortInputType : SortInputType<Item> { protected override void Configure(ISortInputTypeDescriptor<Item> descriptor) { base.Configure(descriptor); // 添加fullName作为可排序字段 descriptor.Field("fullName").Type<StringSortInputType>(); } }
2. 在查询方法中指定自定义排序类型
修改GetItems上的UseSorting特性,指定使用你刚创建的自定义排序输入类型,同时在方法里手动处理fullName的排序:
[UseFiltering] [UseSorting(typeof(ItemSortInputType))] public async Task<IEnumerable<Item>> GetItems( int age, CancellationToken cancellationToken = default ) { var items = // 从数据库或其他数据源获取原始Item列表 // 手动根据fullName的规则排序 return items.OrderBy(item => $"{item.FirstName} {item.LastName}"); }
⚠️ 注意:这种方式是在内存中做排序,如果数据量很大的话会有性能问题,因为没法把排序逻辑转换成SQL语句推送到数据库执行。
额外检查:你的代码有个小错误
在ItemType的Configure方法里,参数类型写的是IObjectTypeDescriptor<FilterTreeItem>,但你的类是ObjectType<Item>,这里类型不匹配,应该改成IObjectTypeDescriptor<Item>,不然可能导致fullName字段没有正确注册:
protected override void Configure(IObjectTypeDescriptor<Item> descriptor) { descriptor .Field("fullName") .Type<StringType>() .ResolveWith<Resolver>(r => r.GetFullName(default!)); // 其他属性配置 }
内容的提问来源于stack exchange,提问作者JrDeveloper

