I came across this bug while using DataGrid's LoadData, and filtering on dataGrid.Where(args.Filter)
. I'm trying to filter a text field so that it Does Not Contain a string.
I'm getting this exception:
System.InvalidOperationException: Invalid predicate: x => (!((((x == null) ? null : x.Comments) ?? "").ToLower() ?? "").Contains("foo"))
---> System.InvalidOperationException: No coercion operator is defined between types 'System.String' and 'System.Boolean'.
The !
filter that gets added should wrap the Property.Contains in parenthesis.
so that its !( [null check and ToLower].Contains('foo') )
This is the fix is in ExpressionSerializer's VisitUnary
Drop this in ExpressionParserTests
[Fact]
public void Support_Test()
{
var filterDescriptor = new FilterDescriptor()
{
Property = "Product.ProductName",
//FilterProperty = c.FilterProperty,
Type = typeof(string),
FilterValue = "foo",
FilterOperator = FilterOperator.DoesNotContain,
//SecondFilterValue = c.GetSecondFilterValue(),
//SecondFilterOperator = c.GetSecondFilterOperator(),
//LogicalFilterOperator = c.GetLogicalFilterOperator()
};
var parameter = Expression.Parameter(typeof(OrderDetail), "x");
var serializer = new ExpressionSerializer();
var expressionBefore = QueryableExtension.GetExpression<OrderDetail>(parameter, filterDescriptor, FilterCaseSensitivity.CaseInsensitive, filterDescriptor.Type);
var lambdaString = serializer.Serialize(Expression.Lambda<Func<OrderDetail, bool>>(expressionBefore, parameter));
var expressionAfter = ExpressionParser.ParsePredicate<OrderDetail>(lambdaString);
var func = expressionAfter.Compile();
Assert.False(func(new OrderDetail() { Product = new Product { ProductName = "foo" } }));
Assert.True(func(new OrderDetail() { Product = new Product { ProductName = "bar" } }));
}