HotChocolate GraphQL содержит запрос в строковом поле, допускающем значение NULL, приводит к исключению нулевой ссылки

В нашем проекте .NET 6 с Entity Framework Core мы используем HotChocolate GraphQL 12.18.0.

Чтобы поддерживать нечувствительные к регистру contains запросы выбора в строковых полях, я добавил обработчик настраиваемого поля:

public class QueryableStringInvariantContainsHandler : QueryableStringOperationHandler
    {
        public QueryableStringInvariantContainsHandler(InputParser inputParser) : base(inputParser)
        {
        }

        protected override int Operation => DefaultFilterOperations.Contains;

        public override Expression HandleOperation(
            QueryableFilterContext context,
            IFilterOperationField field,
            IValueNode value,
            object parsedValue)
        {
            Expression property = context.GetInstance();
            return parsedValue is string str
                ? (Expression)Expression.NotEqual(
                        Expression.Call(
                            property,
                            typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) }),
                            Expression.Constant(str),
                            Expression.Constant(StringComparison.OrdinalIgnoreCase)
                        ),
                        Expression.Constant(-1)
                    )
                : throw new InvalidOperationException();
        }
    }
public class CustomFilteringConvention : FilterConvention
    {
        protected override void Configure(IFilterConventionDescriptor descriptor)
        {
            _ = descriptor.AddDefaults();
            _ = descriptor.Operation(DefaultFilterOperations.Equals).Name("equals");
            _ = descriptor.AddProviderExtension(
                new QueryableFilterProviderExtension(x =>
                {
                    _ = x.AddFieldHandler<QueryableStringInvariantContainsHandler>();
                }));
        }
    }

В запросе graphql его можно использовать следующим образом:

[...]
where: {
        or: [
          { givenName: { contains:$searchQuery}}
          { surname: { contains:$searchQuery}}
          { background: { contains:$searchQuery}}
        ]
[...]

Он работает нормально, пока в базе данных нет нулевых значений для отфильтрованных строковых полей. В полях с нулевыми значениями в базе данных происходит сбой с исключением нулевой ссылки. Как заставить запрос работать со значениями NULL в базе данных?

Покажите код (классы, сопоставления, код, вызывающий исключение). Улучшение вопроса гораздо полезнее, чем предложение вознаграждения за вопрос, на который нет ответа.

Gert Arnold is on strike 11.05.2023 16:43
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
0
1
87
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не понимаю ваш вопрос. В случае строк, если вы хотите включить нули в операцию или, вы должны использовать операнд eq:

{ stringField1: { eq:""}}
Ответ принят как подходящий

В конце концов я нашел решение сам:

public class QueryableStringInvariantContainsHandler : QueryableStringOperationHandler
    {
        public QueryableStringInvariantContainsHandler(InputParser inputParser) : base(inputParser)
        {
        }

        protected override int Operation => DefaultFilterOperations.Contains;

        public override Expression HandleOperation(
            QueryableFilterContext context,
            IFilterOperationField field,
            IValueNode value,
            object parsedValue)
        {
            Expression property = context.GetInstance();
            return parsedValue is string str
                ? (Expression)Expression.AndAlso(
                    Expression.NotEqual(property, Expression.Constant(null, typeof(object))),
                    Expression.NotEqual(
                        Expression.Call(
                            property,
                            typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) }),
                            Expression.Constant(str),
                            Expression.Constant(StringComparison.OrdinalIgnoreCase)
                        ),
                        Expression.Constant(-1)
                    )
                )
                : throw new InvalidOperationException();
        }
    }

Это также будет учитывать значения NULL

Другие вопросы по теме