diff --git a/src/BlazorTable/Filters/StringFilter.razor.cs b/src/BlazorTable/Filters/StringFilter.razor.cs index dbb3672a..67d222ee 100644 --- a/src/BlazorTable/Filters/StringFilter.razor.cs +++ b/src/BlazorTable/Filters/StringFilter.razor.cs @@ -28,29 +28,33 @@ protected override void OnInitialized() { bool NotCondition = false; - Expression method; + Expression method = Column.Filter.Body; - if (Column.Filter.Body is UnaryExpression unary) + if (method is BinaryExpression binary) { - NotCondition = unary.NodeType == ExpressionType.Not; + method = binary.Right; + } - method = unary.Operand; + if (method is BinaryExpression binary2) + { + NotCondition = binary2.NodeType == ExpressionType.LessThanOrEqual; + method = binary2.Left; } - else + + if (method is UnaryExpression unary1) { - method = Column.Filter.Body; + NotCondition = unary1.NodeType == ExpressionType.Not; + method = unary1.Operand; } if (method is MethodCallExpression methodCall) { - var MethodName = methodCall.Method.Name; - - if (methodCall.Arguments[0] != null && methodCall.Arguments[0] is ConstantExpression constantExpression) + if (methodCall.Arguments[0] is ConstantExpression constantExpression) { - FilterText = constantExpression.Value.ToString(); + FilterText = constantExpression.Value?.ToString(); } - Condition = GetConditionFromMethod(MethodName, NotCondition); + Condition = GetConditionFromMethod(methodCall.Method.Name, NotCondition); } } } @@ -58,11 +62,11 @@ protected override void OnInitialized() private StringCondition GetConditionFromMethod(string method, bool not) { - if (method == nameof(string.Contains) && !not) + if (method == nameof(string.IndexOf) && !not) { return StringCondition.Contains; } - else if (method == nameof(string.Contains) && not) + else if (method == nameof(string.IndexOf) && not) { return StringCondition.DoesNotContain; } @@ -88,7 +92,7 @@ private StringCondition GetConditionFromMethod(string method, bool not) } else if (method == nameof(string.IsNullOrEmpty) && not) { - return StringCondition.IsNullOrEmpty; + return StringCondition.IsNotNulOrEmpty; } throw new InvalidOperationException("Shouldn't be here"); @@ -97,25 +101,89 @@ private StringCondition GetConditionFromMethod(string method, bool not) public Expression> GetFilter() { FilterText = FilterText?.Trim(); - + switch (Condition) { case StringCondition.Contains: - return Utillities.CallMethodType(Column.Field, typeof(string), nameof(string.Contains), typeof(string), FilterText); + return Expression.Lambda>( + Expression.AndAlso( + Expression.NotEqual(Column.Field.Body, Expression.Constant(null)), + Expression.GreaterThanOrEqual( + Expression.Call( + Column.Field.Body, + typeof(string).GetMethod(nameof(string.IndexOf), new[] { typeof(string), typeof(StringComparison) }), + new[] { Expression.Constant(FilterText), Expression.Constant(StringComparison.OrdinalIgnoreCase) }), + Expression.Constant(0))), + Column.Field.Parameters); + case StringCondition.DoesNotContain: - return Utillities.CallMethodType(Column.Field, typeof(string), nameof(string.Contains), typeof(string), FilterText).Not(); + return Expression.Lambda>( + Expression.AndAlso( + Expression.NotEqual(Column.Field.Body, Expression.Constant(null)), + Expression.LessThanOrEqual( + Expression.Call( + Column.Field.Body, + typeof(string).GetMethod(nameof(string.IndexOf), new[] { typeof(string), typeof(StringComparison) }), + new[] { Expression.Constant(FilterText), Expression.Constant(StringComparison.OrdinalIgnoreCase) }), + Expression.Constant(-1))), + Column.Field.Parameters); + case StringCondition.StartsWith: - return Utillities.CallMethodType(Column.Field, typeof(string), nameof(string.StartsWith), typeof(string), FilterText); + return Expression.Lambda>( + Expression.AndAlso( + Expression.NotEqual(Column.Field.Body, Expression.Constant(null)), + Expression.Call( + Column.Field.Body, + typeof(string).GetMethod(nameof(string.StartsWith), new[] { typeof(string), typeof(StringComparison) }), + new[] { Expression.Constant(FilterText), Expression.Constant(StringComparison.OrdinalIgnoreCase) })), + Column.Field.Parameters); + case StringCondition.EndsWith: - return Utillities.CallMethodType(Column.Field, typeof(string), nameof(string.EndsWith), typeof(string), FilterText); + return Expression.Lambda>( + Expression.AndAlso( + Expression.NotEqual(Column.Field.Body, Expression.Constant(null)), + Expression.Call( + Column.Field.Body, + typeof(string).GetMethod(nameof(string.EndsWith), new[] { typeof(string), typeof(StringComparison) }), + new[] { Expression.Constant(FilterText), Expression.Constant(StringComparison.OrdinalIgnoreCase) })), + Column.Field.Parameters); + case StringCondition.IsEqualTo: - return Utillities.CallMethodType(Column.Field, typeof(string), nameof(string.Equals), typeof(string), FilterText); + return Expression.Lambda>( + Expression.AndAlso( + Expression.NotEqual(Column.Field.Body, Expression.Constant(null)), + Expression.Call( + Column.Field.Body, + typeof(string).GetMethod(nameof(string.Equals), new[] { typeof(string), typeof(StringComparison) }), + new[] { Expression.Constant(FilterText), Expression.Constant(StringComparison.OrdinalIgnoreCase) })), + Column.Field.Parameters); + case StringCondition.IsNotEqualTo: - return Utillities.CallMethodType(Column.Field, typeof(string), nameof(string.Equals), typeof(string), FilterText).Not(); + return Expression.Lambda>( + Expression.AndAlso( + Expression.NotEqual(Column.Field.Body, Expression.Constant(null)), + Expression.Not( + Expression.Call( + Column.Field.Body, + typeof(string).GetMethod(nameof(string.Equals), new[] { typeof(string), typeof(StringComparison) }), + new[] { Expression.Constant(FilterText), Expression.Constant(StringComparison.OrdinalIgnoreCase) }))), + Column.Field.Parameters); + case StringCondition.IsNullOrEmpty: - return Utillities.CallMethodTypeStaticSelf(Column.Field, typeof(string), nameof(string.IsNullOrEmpty), typeof(string)); + return Expression.Lambda>( + Expression.Call( + typeof(string).GetMethod(nameof(string.IsNullOrEmpty), new[] { typeof(string)}), + Column.Field.Body), + Column.Field.Parameters); + case StringCondition.IsNotNulOrEmpty: - return Utillities.CallMethodTypeStaticSelf(Column.Field, typeof(string), nameof(string.IsNullOrEmpty), typeof(string)).Not(); + return Expression.Lambda>( + Expression.Not( + Expression.Call( + typeof(string).GetMethod(nameof(string.IsNullOrEmpty), new[] { typeof(string)}), + Column.Field.Body)), + Column.Field.Parameters); + default: throw new ArgumentException(Condition + " is not defined!"); } diff --git a/src/BlazorTable/Utillities.cs b/src/BlazorTable/Utillities.cs index beb850cc..625b0970 100644 --- a/src/BlazorTable/Utillities.cs +++ b/src/BlazorTable/Utillities.cs @@ -78,30 +78,6 @@ public static string GetDescription(this T e) where T : IConvertible return null; // could also return string.Empty } - public static Expression> CallMethodType(Expression> expression, Type type, string method, Type parameter, object value) - { - return CallMethodType(expression, type, method, new[] { parameter }, new[] { value }); - } - - public static Expression> CallMethodType(Expression> expression, Type type, string method, Type[] parameters, object[] values) - { - return Expression.Lambda>( - Expression.Call( - expression.Body, - type.GetMethod(method, parameters), - values.OrEmptyIfNull().Select(Expression.Constant)), - expression.Parameters); - } - - public static Expression> CallMethodTypeStaticSelf(Expression> expression, Type type, string method, Type parameter) - { - return Expression.Lambda>( - Expression.Call( - type.GetMethod(method, new[] { parameter }), - expression.Body), - expression.Parameters); - } - public static Type GetMemberUnderlyingType(this MemberInfo member) { switch (member.MemberType) @@ -132,10 +108,5 @@ public static MemberInfo GetPropertyMemberInfo(this Expression> Not(this Expression> expression) - { - return Expression.Lambda>(Expression.Not(expression.Body), expression.Parameters[0]); - } } }