Combine 'Contains' with 'ToLower' in dynamic expression

267 views Asked by At

I'm building a generic search using expressions, searching in all string properties of the model. However I'm having problems implementing 'Contains' alongside 'ToLower'.

    Type elementType = typeof(TItem);
    PropertyInfo[] stringProperties = elementType.GetProperties()
            .Where(x => x.PropertyType == typeof(string))
            .ToArray();

    MethodInfo containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) })!;
    MethodInfo toLowerMethod = typeof(string).GetMethod("ToLower", Type.EmptyTypes);


    ParameterExpression paramExp = Expression.Parameter(elementType);

    IEnumerable<Expression> expressions = stringProperties
        .Select(p=> Expression.Call(Expression.Property(paramExp, p), containsMethod, Expression.Constant(this.searchString.ToLower()))
        );


    Expression body = expressions.Aggregate((prev, current) => Expression.Or(prev, current));
    var lambda = Expression.Lambda<Func<TItem, bool>>(body, paramExp);

Any ideas how I could achieve this?

1

There are 1 answers

0
Tim Schmelter On

You should be able to use the overload of Contains with StringComparison:

MethodInfo containsMethod = typeof(string).GetMethod("Contains", 
    new[] { typeof(string), typeof(StringComparison) })!;

IEnumerable<Expression> expressions = stringProperties
    .Select(p => Expression.Call(Expression.Property(paramExp, p), 
        containsMethod, 
        Expression.Constant(searchString), 
        Expression.Constant(StringComparison.OrdinalIgnoreCase))
    );