3

Consider following lambda expression:

IQueryable<Product> query = query.Where(x => x.ProductName.Contains("P100"));

I need to convert above code something like this:

IQueryable<Product> query = query.Where(x => x.GetPropertyValue("ProductName").Contains("P100"));

Here I have added a dummy method GetPropertyValue("ProductName") to explain the requirement. In above code the property should be resolved in run-time. In other words I need to access the property from a sting value E.g "ProductName"

How can I do this?

Rahul
  • 2,431
  • 3
  • 35
  • 77
  • I mean I have to make this method more generic. According to my application logic I only have the property name as a string value. So i need to resolve the string as a property. – Rahul Mar 27 '16 at 08:06
  • What's your query processor? Will it even support using a `GetPropertyValue()` method on a `Product` object? There's no point in doing the conversion if it's not supported. – Jeff Mercado Mar 27 '16 at 08:25
  • 1
    You need to learn either Linq Expressions, or you need to use Dynamic Linq. – Aron Mar 27 '16 at 09:40
  • @DavidG This is a completely different question from the one you are referencing, given that using Reflection will not work with most Linq Providers. – Aron Mar 01 '18 at 17:58

2 Answers2

9
var parameterExp = Expression.Parameter(typeof(Product), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);

Expression<Func<Product, bool>> predicate = Expression.Lambda<Func<T, bool>>
             (containsMethodExp, parameterExp);


var query = query.Where(predicate);
Aron
  • 15,464
  • 3
  • 31
  • 64
  • Can this easily transferred to just a linq `where` call without the contains bit? – Douglas Gaskell Feb 22 '18 at 04:16
  • @DouglasGaskell What do you mean without the contains bit? The above code is for generating a pure Linq expression tree without any CLR. Which allows this query to run in most Linq Providers including non CLR backed providers like EF or nHiberate. – Aron Feb 22 '18 at 07:12
1

You can have this extension method:

public static T GetPropertyValue<T>(this Product product, string propName)
{
   return (T)typeof(Product).GetProperty(propName).GetValue(product, null);
}

Then:

IQueryable<Product> query = query.Where(x => x.GetPropertyValue<string>("ProductName").Contains("P100"));

Notice that this will not work with Entity Framework to query a database, but since you haven't tagged the question with entity framework, I'm not assuming you are using it

Jcl
  • 27,696
  • 5
  • 61
  • 92
  • I'm using Odata V4 with Odata Client code generator. will this work? – Rahul Mar 27 '16 at 19:22
  • I never used it, I don't know, but if it's pertinent to the question (and it is), you should have specified it (or at least tagged the question) – Jcl Mar 27 '16 at 19:24