Expression Trees on DataTable

c# dynamic-linq expression-trees linq

Question

I am trying to build a DataTable filter with ExpressionTrees now I made a QueryBuilder helper class as shown below. The call would be like so:

                var pb = PredicateBuilder.True<DataRowCollection>();
                int i = 0;
                foreach (var key in keys)
                {
                    pb.And<DataRowCollection>(QueryBuilder.CompareProperty<DataRowCollection>(key.Code, value[key.Code]));
                    i++;
                }
                var qs = qt.Where(pb);

now the prblems is I am having is that I get an error like so:

'System.Data.EnumerableRowCollection<System.Data.DataRow>' does not contain a definition for 'Where' and the best extension method overload 'System.Data.EnumerableRowCollectionExtensions.Where<TRow>(System.Data.EnumerableRowCollection<TRow>, System.Func<TRow,bool>)' has some invalid argument
Argument 2: cannot convert from 'System.Linq.Expressions.Expression<System.Func<System.Data.DataRowCollection,bool>>' to 'System.Func<System.Data.DataRow,bool>'

Helper classes:

public class QueryBuilder
{
    public static Expression<Func<T, bool>> Compare<T>(T rhs, ExpressionType op)
    {

    var lhsParam = Expression.Parameter(typeof(T), "x");
    var rhsParam = Expression.Constant(rhs);

    var binaryExp = Expression.MakeBinary(op, lhsParam, rhsParam);
    var theLambda = Expression.Lambda<Func<T, bool>>(binaryExp, lhsParam);

    return theLambda;
}

public static Expression<Func<T, bool>> Between<T>(T lower, T upper)
{
    var predicateInner = PredicateBuilder.True<T>();
    predicateInner = predicateInner.And(Compare<T>(lower, ExpressionType.GreaterThan));
    predicateInner = predicateInner.And(Compare<T>(upper, ExpressionType.LessThan));

    return predicateInner;
}

public static Expression<Func<T,bool>>  CompareProperty<T>(string propertyName, dynamic criteria)
{
    ParameterExpression pe = Expression.Parameter(typeof(T), "t");
    Expression np = Expression.Property(pe, propertyName);
    ConstantExpression value = Expression.Constant(criteria);

    Expression eq = Expression.Equal(np, value);
    var filter = Expression.Lambda<Func<T, bool>>(eq, pe);

    return filter;
}

}

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>> True<T>(IQueryable<T> query) { return f => true; }
    public static Expression<Func<T, bool>> False<T>(IQueryable<T> query) { 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);
    }
}

I know that there is something called dynamic Linq but I would like to see how this is done with expression trees :)

Hope someone can help.

1
3
5/15/2015 10:02:41 PM

Popular Answer

You do not need lambda expressions to search in memory. Don't overcomplicate your life, just create delegates (Func<T, bool>) and use them, much easier to write, handle and debug!

1
5/16/2015 11:22:19 AM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow