AJC
AJC

Reputation: 1893

Use reflection to get lambda expression from property Name

I want to give the user the choice of searching by different properties. For instance

[INPUT TEXT] | [SELECT OPTION {ID, NAME, PHONE}] | [SEARCH]

And I would later build my query like this:

repository.Where(lambda-expression)

Where lambda-expression is build from the selected option {ID, NAME, PHONE} (For example: x => x.NAME.Equals(INPUT TEXT))

Is there a way to build the lambda from the Property name perhaps using reflection?

Thanks

Upvotes: 8

Views: 14621

Answers (3)

Mudasser
Mudasser

Reputation: 31

I had to face the same sort of problem and the following method resolved my problem perfectly.

PropertyInfo propertyInfoObj = MyClassObject.GetType().GetProperty(PropertyName);
repository.Where(x => propertyInfoObj.GetValue(x) == SearchValue).Select(x => propertyInfoObj.GetValue(x)).FirstOrDefault();

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1500535

You don't build a lambda expression - you build an expression tree. It's not terribly hard, but it takes a little patience. In your sample you'd probably need:

ParameterExpression parameter = Expression.Parameter(typeof(Foo), "x");
Expression property = Expression.Property(parameter, propertyName);
Expression target = Expression.Constant(inputText);
Expression equalsMethod = Expression.Call(property, "Equals", null, target);
Expression<Func<Foo, bool>> lambda =
   Expression.Lambda<Func<Foo, bool>>(equalsMethod, parameter); 

That's assuming:

  • The repository element type is Foo
  • You want to use a property called propertyName
  • You want to compare for equality against inputText

Upvotes: 26

Icarus
Icarus

Reputation: 63966

For that sort of thing, I use something like this (note: does a Where "Like") :

 public static IQueryable<TEntity> Where<TEntity>(this IQueryable<TEntity> source, string propertyName, string value) 
    {

        Expression<Func<TEntity, bool>> whereExpression = x => x.GetType().InvokeMember(propertyName, BindingFlags.GetProperty, null, x, null).ObjectToString().IndexOf(value, StringComparison.InvariantCultureIgnoreCase) >= 0;

        return source.Where(whereExpression);


    }

Upvotes: 3

Related Questions