I'm trying to build a single "Or" predicate from a list of predicates in the form List<Expression<Func<T, bool>>>
public static IQueryable<T> Search<T>(this IQueryable<T> source, List<Expression<Func<T, bool>>> predicates = null)
where T : EntityObject
{
if (predicates == null || predicates.Count == 0)
return source;
else if (predicates.Count == 1)
return source.Where(predicates[0]);
else
{
var row = Expression.Parameter(typeof(T), "row");
var compoundExpression = predicates[0];
for (int i = 1; i < predicates.Count; i++)
{
compoundExpression = compoundExpression.Or(predicates[i]);
}
return source.Where(compoundExpression);
}
}
static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> lhs, Expression<Func<T, bool>> rhs)
{
var row = Expression.Parameter(typeof(T), "row");
var body = Expression.Or(
Expression.Invoke(lhs, row),
Expression.Invoke(rhs, row));
return Expression.Lambda<Func<T, bool>>(body, row);
}
But this is returning every row in my source?
For testing I am looking for c=>c.FullName.Contains("Smith") or c=>c.FullName.Contains("Jones")
I have tried amending to use PredicateBuilder but again it still returns every row in the source.
public static IQueryable<T> Search<T>(this IQueryable<T> source, List<Expression<Func<T, bool>>> predicates = null)
where T : EntityObject
{
if (predicates == null || predicates.Count == 0)
return source;
else if (predicates.Count == 1)
return source.Where(predicates[0]);
else
{
var pb = PredicateBuilder.False<T>();
for (int i = 0; i < predicates.Count; i++)
{
pb = pb.Or(predicates[i]);
}
return source.AsExpandable().Where(pb);
}
}
Any assistance very gratefully received!
The end result would be to allow AND's as well as OR's
e.g. c=>c.FullName.Contains("Dav") AND c=>c.CustomerType == 'Staff'