Friday, September 18, 2015

Build Where Clause Dynamically Using Linq PredicateBuilder to filter data from DataTable C#

To filter some data from a DataTable based on two or more condition is not possible using the below code. As the Linq where condition not allowed more than one condition.
var filtered = dataTable.Where(x => x["Name"].Equals("Venkat") && x => x["Age"].Equals("26")).ToList()

So using the PredicateBuilder we can build where clause dynamically. Check the below code.,

As you can see, the below code is constructing the where clause dynamically. You can pass multiple column name and value as filter condition dynamically.
var predicate = PredicateBuilder.True();
predicate = predicate.And(x => x["Name"].Equals("Venkat"));
predicate = predicate.And(x => x["Age"].Equals("26"));
predicate.Compile();
var filtered = dataTable.Where(predicate).ToList();

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);
    }
}