4

I am constructing an IQueryable query using several methods. The methods are somehow complex, but the problem I want to solve can be extracted and simplified as follows. I have two methods

private Expression<Func<T, bool>> CreateExpressionA(string ValueA)
{
  return a => a.PropertyA.ToLower() == ValueA;
}

private Expression<Func<T, bool>> CreateExpressionB(string ValueB)
{
  return a => a.PropertyB.ToLower() == ValueB;
}

and what I would rather have is this:

private Expression<Func<T, bool>> CreateExpression(??? Selector, string Value)
{
  return a => a.Selector.ToLower() == Value;
}

or a similar approach that would allow me to avoid having two same methods with the only difference being in what property of an object is being used there.

Is it possible to do this in some elegant way?

2
  • 1
    It's quite easy with reflection, I guess... Commented Nov 14, 2016 at 14:04
  • It surely is (as I see in the answers), I just did not know how exactly to write it. But I like the non-reflection answer even more. Commented Nov 14, 2016 at 14:32

3 Answers 3

4

You can pass in a selector Func that returns a string property:

private Expression<Func<T, bool>> CreateExpression<T>(Func<T, string> selector, string value)
{
    return a => selector(a).ToLower() == value;
}

Usage:

CreateExpression<MyType>(x => x.PropertyA, "thevalue");
Sign up to request clarification or add additional context in comments.

1 Comment

I love this solution. This is exactly what I was looking for, and it works well. Thanks!
1

You could use reflection, more precisely the class PropertyInfo as an argument, but the implementation would be more involved. The method could be implemented as follows.

private Expression<Func<T, bool>> CreateExpression(PropertyInfo iInfo, string Value)
{
    return a => (iInfo.GetPropertyValue(a) as string).ToLower() == ValueB;
}

However, note that this will work only if the type of the property is string, otherwise an additional type parameter could be used.

Comments

0

What you can do is create the Expression from scratch:

private Expression<Func<T, bool>> CreateExpression(string propertyName, string value) {
    ParameterExpression param = Expression.Parameter(typeof(T));
    MemberExpression property = Expression.Property(param, propertyName);
    var valExpr = Expression.Constant(value);
    var body = Expression.Equal(property, valExpr);
    return Expression.Lambda<Func<T, bool>>(body, param);
}

Call with:

var expression = CreateExpression<TypeOfA>("PropertyA", "ValueForPropertyA");

It's a bit off the top of my head, but I think this should at least get you started. Let me know if you need help.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.