tags:

views:

4451

answers:

2

I created a filterable BindingList from this source: http://www.nablasoft.com/alkampfer/index.php/2008/11/22/extend-bindinglist-with-filter-functionality/

It works great (

list.Filter("Customer == 'Name'");

does what it should. In the internals works a parser, that converts the expression "==" or "!=" into "System.Linq.Expressions.Expression", in this case (==) :

System.Linq.Expressions.Expression.Equal

Unfortunatly System.Linq.Expressions.Expression does not contain a like operator. But I am to much beginner with linq and I don't know how to solve this.

The initial code looks like this:

 private static Dictionary<String, Func<Expression, Expression, Expression>> 
  binaryOpFactory = new Dictionary<String, Func<Expression, Expression, Expression>> ();

      static Init() {

  binaryOpFactory.Add("==", Expression.Equal);
  binaryOpFactory.Add(">", Expression.GreaterThan);
  binaryOpFactory.Add("<", Expression.LessThan);
  binaryOpFactory.Add(">=", Expression.GreaterThanOrEqual);
  binaryOpFactory.Add("<=", Expression.LessThanOrEqual);
  binaryOpFactory.Add("!=", Expression.NotEqual);
  binaryOpFactory.Add("&&", Expression.And);
  binaryOpFactory.Add("||", Expression.Or);

      }

Now I created an expression, that will do what I want:

    private static System.Linq.Expressions.Expression<Func<String, String, bool>>
            Like_Lambda = (item, search) => item.ToLower().Contains(search.ToLower());
    private static Func<String, String, bool> Like = Like_Lambda.Compile();

e.g.

    Console.WriteLine(like("McDonalds", "donAld")); // true
    Console.WriteLine(like("McDonalds", "King"));   // false

But the binaryOpFactory requires this

    Func<Expression, Expression, Expression>

The predefined expressions seem to be exactly that:

    System.Linq.Expressions.Expression.Or;

Can anyone tell me howto convert my expression?

+4  A: 

Something like:

static IEnumerable<T> WhereLike<T>(
        this IEnumerable<T> data,
        string propertyOrFieldName,
        string value)
{
    var param = Expression.Parameter(typeof(T), "x");
    var body = Expression.Call(
        typeof(Program).GetMethod("Like",
            BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public),
            Expression.PropertyOrField(param, propertyOrFieldName),
            Expression.Constant(value, typeof(string)));
    var lambda = Expression.Lambda<Func<T, bool>>(body, param);
    return data.Where(lambda.Compile());
}
static bool Like(string a, string b) {
    return a.Contains(b); // just for illustration
}


In terms of a Func<Expression,Expression,Expression>:

static Expression Like(Expression lhs, Expression rhs)
{
    return Expression.Call(
        typeof(Program).GetMethod("Like",
            BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
            ,lhs,rhs);
}
Marc Gravell
looks nice thx, but I need sth. that returns a Func<Expression, Expression, Expression> But the question is, what is expression1, expression2 and expression3 in this context? A example how Expression.Equal works internally whould be nice.
SchlaWiener
I must admit, I do not understand the whole magic behind the code, but the second pice of code works like a charm.
SchlaWiener
+1  A: 

you can use expression.contains instead

abdulkaderjeelani
`System.Linq.Expressions.Expression` does not provide a predefined contains method (at least not in 3.5)The last code bit from Marc shows how to create your own expression implementations (which in my case uses contains internally) which is great.
SchlaWiener