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.
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))));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With