3

The code below work, but I'd like introduce a ToUpper()

var predicate =
    Expression.Lambda<Func<T, bool>>(
        Expression.Call(
            Expression.PropertyOrField(parameter, "FirstName"),
            "Contains", null,
            Expression.Constant("myvalue".ToUpper())), parameter
        );

The result is :

{Param_0 => Param_0.FirstName.Contains("MYVALUE")}

But I'd like this :

{Param_0 => Param_0.FirstName.ToUpper().Contains("MYVALUE")}

How can I change ?

Dillon Benson
  • 4,280
  • 4
  • 23
  • 25
TheBoubou
  • 19,487
  • 54
  • 148
  • 236

2 Answers2

9

Just add an Expression.Call:

var predicate =
    Expression.Lambda<Func<T, bool>>(
        Expression.Call(
            Expression.Call( // <=== this one is new
                Expression.PropertyOrField(parameter, "FirstName"),
                "ToUpper", null),
            "Contains", null,
            Expression.Constant("myvalue".ToUpper())), parameter
        );

which then reports itself as:

Param_0 => Param_0.FirstName.ToUpper().Contains("MYVALUE")
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
6

EDIT: Okay, I'd misread the question. The problem is that you're calling Contains directly on the result of calling the FirstName property. You need to call ToUpper on the property first, e.g.

var firstName = Expression.PropertyOrField(parameter, "FirstName");
var firstNameUpper = Expression.Call(firstName, "ToUpper", null);
var target = Expression.Constant("myvalue".ToUpper());
var contains = Expression.Call(firstNameToUpper, "Contains", null, target);
var lambda = Expression.Lambda<Func<T, bool>>(contains, parameter);

Note that this isn't "culturally-safe" - it would be safer to use a case-insensitive comparison instead. This question shows an approach using IndexOf, but that may not be supported by your LINQ provider (I don't know what you're doing with this expression tree afterwards).

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks Jon. But it's not the result I want. I'd like make a ToUpper() on the values coming from "FirstName" before do the a "Contains" where the string is already uppercase. – TheBoubou Dec 21 '12 at 08:34
  • Jon, or if it's easier do a "Contains" with an IgnoreCase – TheBoubou Dec 21 '12 at 09:04
  • @Kris-I: I've edited the answer for the tree you were looking for, but I'll see if I can find a better approach. – Jon Skeet Dec 21 '12 at 09:10