I'm trying to create my own filter for a specific type of data in hotchocolate.
I created a class from FilterInputType<MyType> and specified an additional field for filtering in it. For this field, I specified my own handler, which I implemented by inheriting from the QueryableOperationHandlerBase class, and also specified this handler in the convention. But it is not processed in any way and does not even go there, what is the reason for this.
I would be grateful if you could provide detailed documentation on this topic or code examples, as hotchocolate has quite scant documentation on this topic.
public class SampleTestFilter : FilterInputType<SampleTest>
{
protected override void Configure(IFilterInputTypeDescriptor<SampleTest> descriptor)
{
base.Configure(descriptor);
descriptor.Field("testKind")
.Type<TestKindFilterType>()
.Extend()
.OnBeforeCreate(x => x.Handler = new TestKindFilterHandler(new InputParser()));
}
}
public class TestKindFilterType : InputObjectType
{
protected override void Configure(IInputObjectTypeDescriptor descriptor)
{
descriptor.Field("value").Type<StringType>();
}
}
public class TestKindFilterHandler : QueryableOperationHandlerBase
{
public TestKindFilterHandler(InputParser inputParser) : base(inputParser)
{
}
public override bool CanHandle(ITypeCompletionContext context, IFilterInputTypeDefinition typeDefinition, IFilterFieldDefinition fieldDefinition)
{
return context is TestKindFilterType;
}
public override Expression HandleOperation(QueryableFilterContext context, IFilterOperationField field, IValueNode value, object? parsedValue)
{
var entity = Expression.Parameter(typeof(SampleTest), "x1");
var parameters = Expression.PropertyOrField(entity, nameof(SampleTest.Parameters));
var entityParameter = Expression.Parameter(typeof(AccountingParameterBase), "x1");
var wrapperValue = Expression.Call(typeof(EF),
nameof(EF.Property),
new[]
{
typeof(object)
},
entityParameter,
Expression.Constant("_wrappedValue"));
var propertyName = Expression.Constant("_valueString");
var propertyValue = Expression.Constant(value.Value.ToString(), typeof(string));
var charValue = Expression.Call(typeof(EF),
nameof(EF.Property),
new[]
{
propertyValue.Type
},
wrapperValue,
propertyName);
var comparison = Expression.Equal(charValue, propertyValue);
var nullValue = Expression.Call(typeof(EF),
nameof(EF.Property),
new[]
{
typeof(object)
},
wrapperValue,
Expression.Constant("_type"));
var nullExp = Expression.Equal(nullValue, Expression.Constant(null));
var condition = comparison;
Expression<Func<AccountingParameterBase, bool>> predicate = Expression.Lambda<Func<AccountingParameterBase, bool>>(condition, entityParameter);
var anyCall = Expression.Call(typeof(Enumerable),
nameof(Enumerable.Any),
new[]
{
typeof(AccountingParameterBase)
},
parameters,
predicate);
var result = Expression.Lambda<Func<SampleTest, bool>>(anyCall, entity);
return result;
}
}
Handler QueryableOperationHandlerBase fails how to make it work. I also tried to make a handler from other base classes of hotchocolate, looked at implementation examples in the source code of hotchocolate.Data. It didn't help.
create my own filter for a specific typewhy? This is an overcomplicated way of adding a.Where()to a LINQ query. And even if there's some justification for this, why use reflection instead of writing theWherequery?it is not processed in any waydid you register this anywhere? Or in the correct place? This shows aFilterInputTypebutTestKindFilterHandlerworks only with EF Core, or at least a source that uses LINQ.