HotChocolate Filters多条件过滤触发NullReferenceException求助
使用HotChocolate.AspNetCore与HotChocolate.Types.Filters NuGet包(版本11.0.9)启用集合过滤功能后,整体过滤正常,但部分查询会在过滤中间件阶段触发NullReferenceException。
经排查,问题根源在于NuGet包中QueryableFilterVisitor生成的IQueryable表达式顺序错误:先检查子属性值,再检查父对象是否非空。调整过滤条件顺序可临时规避异常,但该方案不适用于当前场景(客户端不知情,无法控制条件顺序),请求提供修复方案。
复现代码
public class Item { public int Id { get; set; } public ItemSetting ItemSetting { get; set; } public IEnumerable<Category> Categories { get; set; } } public class ItemSetting { public int Data { get; set; } } public class Category { public string Name { get; set; } } [UseFiltering] public IEnumerable<Item> GetItems() { return [ new Item { Id = 1, ItemSetting = new ItemSetting { Data = 123 }, Categories = [ new Category { Name = "Cat1" }] }, new Item { Id = 2, ItemSetting = null, Categories = [ new Category { Name = "Cat2" }] } ]; }
触发异常的查询
query { items(where: {categories_some: {name: "Cat1"}, itemSetting: {data: 123}}) { id itemSetting { data } categories { name } } }
错误信息
{ "errors": [ { "message": "Unexpected Execution Error", "locations": [ { "line": 2, "column": 3 } ], "path": [ "items" ], "extensions": { "message": "Object reference not set to an instance of an object.", "stackTrace": " at lambda_method83(Closure, Item)\r\n at System.Linq.Enumerable.WhereEnumerableIterator
1.MoveNext()\r\n at HotChocolate.Execution.Processing.ResolverTask.<>c__DisplayClass13_0.<ExecuteResolverPipelineAsync>b__0()\r\n at System.Threading.Tasks.Task1.InnerInvoke()\r\n at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)\r\n--- End of stack trace from previous location ---\r\n at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)\r\n at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)\r\n--- End of stack trace from previous location ---\r\n at HotChocolate.Execution.Processing.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\r\n at HotChocolate.Execution.Processing.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)" } } ], "data": { "items": null } }
无异常的查询(调整条件顺序后)
items(where: { itemSetting: {data: 123}, categories_some: {name: "Cat1"}})
内容的提问来源于stack exchange,提问作者OleLu

