Bakri
Bakri

Reputation: 707

Lambda Expression for dynamic Object

I am trying to build a Lambda Expression for a table that has been created at run time. The Expression is build fine but when I call Compile() method I get this error "ParameterExpression of type 'cseval.Item' cannot be used for delegate parameter of type 'System.Object'" this is my function

    public Func<dynamic, Boolean> GetWhereExp(List<WhereCondition> SearchFieldList, dynamic item)
    {

        ParameterExpression pe = Expression.Parameter(item.GetType(), "c");

        Expression combined = null;

        if (SearchFieldList != null)
        {
            foreach (WhereCondition fieldItem in SearchFieldList)
            {
                //Expression for accessing Fields name property
                Expression columnNameProperty = Expression.Property(pe, fieldItem.ColumName);


                //the name constant to match 
                Expression columnValue = Expression.Constant(fieldItem.Value);

                //the first expression: PatientantLastName = ?
                Expression e1 = Expression.Equal(columnNameProperty, columnValue);

                if (combined == null)
                {
                    combined = e;
                }
                else
                {
                    combined = Expression.And(combined, e);
                }
            }
        }
        var result = Expression.Lambda<Func<dynamic, bool>>(combined, pe);
        return result.Compile();
    }

Upvotes: 2

Views: 6915

Answers (1)

omikad
omikad

Reputation: 1009

I've changed dynamic to generics, this code works for me:

    public Func<T, Boolean> GetWhereExp<T>(List<WhereCondition> SearchFieldList, T item)
    {
        var pe = Expression.Parameter(item.GetType(), "c");
        Expression combined = null;
        if (SearchFieldList != null)
        {
            foreach (var fieldItem in SearchFieldList)
            {
                var columnNameProperty = Expression.Property(pe, fieldItem.ColumName);
                var columnValue = Expression.Constant(fieldItem.Value);
                var e1 = Expression.Equal(columnNameProperty, columnValue);
                combined = combined == null ? e1 : Expression.And(combined, e1);
            }
        }
        var result = Expression.Lambda<Func<T, bool>>(combined, pe);
        return result.Compile();
    }

Small remark: your method returns function, not an expression, so the name 'GetWhereExp' is slightly incorrect. If you want to return function, imho, it's better to use reflection.

UPD: I use this code to test:

            var expressions = new List<WhereCondition>
                {
                    new WhereCondition("Column1", "xxx"),
                    new WhereCondition("Column2", "yyy"),
                };

            var item = new
                {
                    Column1 = "xxx",
                    Column2 = "yyy"
                };

            var func = LinqExpr.GetWhereExp(expressions, (dynamic)item);

            Console.WriteLine(new[] {item}.Count(a => func(a)));

Upvotes: 3

Related Questions