Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expression builder function for String.Contains and string[]

I'm having a hard time creating an expression builder function to pass to a query for NHibernate repository.

Basically what I want to be able to do is build a query from various object properties (strings) and compare their value to values in an array. Also be able to add other query sentences.

Something like

public static Expression<Func<TElement, bool>> BuildOrExpression<TElement, TValue>
    (Dictionary<Expression<Func<TElement, TValue>>, IEnumerable<TValue>> expressionSet)
{
    List<Expression> newExpressions = new List<Expression>();

    foreach (var item in expressionSet)
    {
        if (null == item.Key) throw new ArgumentNullException("valueSelector");
        if (null == item.Value) throw new ArgumentNullException("values");

        ParameterExpression p = item.Key.Parameters.Single();

        if (!item.Value.Any()) return e => false;

        IEnumerable<Expression> expressions = item.Value
           .Select(value => (Expression)Expression.Equal(item.Key.Body, Expression.Constant(value, typeof(TValue))));
        Expression compExpression = expressions
            .Aggregate<Expression>((accumulate, equal) => Expression.OrElse(accumulate, equal));
        newExpressions.Add(Expression.Lambda<Func<TElement, bool>>(compExpression, p));
    }

    Expression accExpression = newExpressions
        .Aggregate<Expression>((accumulate, equal) => Expression.OrElse(accumulate, equal));

    return Expression.Lambda<Func<TElement, bool>>(accExpression);
}

But instead of doing the Expression.Equal somehow doing a String.Contains.

Any help welcomed. By the way the code above is not tested.

like image 977
Fabricio Martínez Tamayo Avatar asked Dec 06 '25 20:12

Fabricio Martínez Tamayo


1 Answers

Instead of Expression.Equal you need to use Expression.Call and pass Contains MethodInfo instance. Something like this

IEnumerable<Expression> expressions = item.Value.Select(value => 
   (Expression)Expression.Call(item.Key.Body, 
   typeof(String).GetMethod("Contains"), 
   Expression.Constant(value, typeof(TValue))));
like image 125
Vladimir Sachek Avatar answered Dec 08 '25 10:12

Vladimir Sachek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!