问题
Suppose I have a method like this:
public void MultiDropDown<T>(Expression<Func<T, DropDownModel<DropDownItem>>> expression)
{
// Here i want to get more specific with the expression selector
// Suppose it was passed like this:
// MultiDropDown(x => x.MyDropDown);
// I need to alter `expression` and go deeper: x => x.MyDropDown.Title;
// And then use the new expression for other stuff...
}
Solution
Thanks to svick !
public void MultiDropDown<T>(Expression<Func<T, DropDownModel<DropDownItem>>> expression)
{
// 1. Build a new expression and select the final property
Expression<Func<DropDownModel<DefaultDropDownItem>, object>> childExpression = x => x.Title;
// 2. Extract property name
var propName = (childExpression.Body as MemberExpression).Member.Name;
// 3. Create a MemberExpression selection from parent's Body
var expressionProperty = Expression.Property(expression.Body, propName);
// 4. Finally create a Lambda Expression
var refinedExpression = Expression.Lambda<Func<TModel, object>>(expressionProperty, expression.Parameters);
}
Operations 1. and 2. were done just for avoiding "Title" string and relying on Strongly Typed model instead.
回答1:
What you need is to create an expression that takes the Body
of your query and accesses the given property on it. Then you need to build back the lambda expression. The whole thing looks like this:
var titleExpression = Expression.Lambda<Func<T, string>>(
Expression.Property(expression.Body, "Title"), expression.Parameters);
来源:https://stackoverflow.com/questions/35732763/alter-lambda-expression-to-go-one-level-deeper