using System.Linq.Expressions;
using System.Collections;
using System.Collections.Generic;
public static void Main()
List<TestEntity> data = new List<TestEntity>();
data.AddRange(new TestEntity[]
new TestEntity("Ahmed", 22, null),
new TestEntity("Ayman", 25, 1500),
new TestEntity("Osama", 26, 7014),
new TestEntity("Mustapha", 14, 1024),
new TestEntity("Mahmoud", 52, 16),
new TestEntity("Muhammed", 23, null),
TestEntity filter = new TestEntity(null, 25, 1500);
var filtered = data.AsQueryable().Where(BuildPredicate<TestEntity>(filter));
foreach(var e in filtered)
Console.WriteLine(e.Name);
public string Name { get; set; }
public int Age { get; set; }
public decimal? Balance { get; set; }
public TestEntity(string name, int age, decimal? balance)
public static Expression<Func<TSource, bool>> BuildPredicate<TSource>(object source)
Expression<Func<TSource, bool>> predicateResult = s => true;
foreach (PropertyInfo property in source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
if (property.PropertyType.IsArray
|| property.PropertyType == typeof(CollectionBase)
|| property.PropertyType == typeof(IQueryable))
object val = property.GetValue(source, null);
if (property.PropertyType != typeof(string))
predicateResult.And(s => s.GetType().GetProperty(property.Name).GetValue(s, null) == property.GetValue(source, null));
predicateResult.And(s => s.GetType().GetProperty(property.Name).GetValue(s, null).ToString().ToLower().Contains(property.GetValue(source, null).ToString().ToLower()));
public static class PredicateBuilder
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);