0

I have an expression of type Expression<Func<TOwner, object>> that was created using lambda (syntax). It has member-access expression somewhere in the body. I would like to create expression that selects another property of the mentioned expression's result.

I terms of C# it should look like this:

Expression<Func<MyClient, object>> exStartingPath = x => x.Address;

Expression<Func<MyClient, object>> exExtendedPath = ExtendSelection(exStartingPath, "Street");
//exExtendedPath should be equivalent to x => x.Address.Street

How should ExtendSelection(...) be implemented? Should I decompose already existing expression and compose new one using some traversing technique or is there any API that can just 'append' member selection?

user3284063
  • 665
  • 5
  • 20
  • try see this [post](http://stackoverflow.com/questions/2797261/mutating-the-expression-tree-of-a-predicate-to-target-another-type?rq=1) and [this](http://stackoverflow.com/questions/29893512/convert-an-expressionfunct-bool-to-an-expressionfunct1-bool-so-that-t-is/29894371#29894371) – Grundy Jun 02 '15 at 18:54
  • @Grundy I fail to see how either of those questions answers this one. – Servy Jun 02 '15 at 19:14
  • What do you mean by somewhere in the body? If you have: Expression> exStartingPath = x => ExtractStreetData(x.Address); then converting the x.Address to x.Street or x.Address.Street might not even result in a valid construct... – MBoros Jun 03 '15 at 11:27

1 Answers1

0

Just grab the body of the lambda, apply the member access to that, and then wrap the whole thing back up into a new lambda.

public static Expression<Func<TSource, TTarget>> ExtendSelection<TSource, TTarget>(
    Expression<Func<TSource, TTarget>> expression, string member)
{
    var body = Expression.PropertyOrField(expression.Body, member);
    return Expression.Lambda<Func<TSource, TTarget>>(body, expression.Parameters);
}
Servy
  • 202,030
  • 26
  • 332
  • 449
  • Is there any way to have the return type to be 'Expression> instead of 'Expression> and without using 'Expression.Convert? As you might guess I want to pass this expression to EF's IQueryable and if I do that with Expression.Convert inside I get exception saying that "Linq 2 Entities supports only casting to enums". – user3284063 Jun 03 '15 at 10:20
  • @user3284063 Sure, you can change all instances of `TTarget` to `object` if you want, but if you supply `object` as the generic argument, or supply an expression returning an `object` in the first place, it'd do the same thing. – Servy Jun 03 '15 at 12:49