I'm using the following approach to get the name of a property specified in a lambda by inspecting the resulting ExpressionTree:
var name =GetPropertyName<Entity1, Entity2>(x => x.Entity2);
public string GetPropertyName<T, P>(Expression<Func<T, P>> expression)
{
var memberExpression = expression.Body as MemberExpression;
var propertyInfo = memberExpression.Member as PropertyInfo;
return propertyInfo.Name;
}
//name is "Entity2"
Given the following expression i want to extract the names "Entity2s", "Entity3s" and "Entity4s"
var names = GetPropertyNames<Entity1, IEnumerable<Entity4>>(x => x.Entity2s.SelectMany(x => x.Entity3s).SelectMany(x => x.Entity4s));
Here is a method for extracting the member names from exactly the Expression
tree you provided. A more generic method should probably be based on an ExpressionVisitor
subclass.
public static List<string> GetPropertyNames<T, P>(Expression<Func<T, P>> fe) {
var ans = new List<string>();
var callExpr1 = fe.Body as MethodCallExpression;
var callExpr2 = callExpr1.Arguments[0] as MethodCallExpression;
var e2MemberExpr1 = callExpr2.Arguments[0] as MemberExpression;
ans.Add(e2MemberExpr1.Member.Name);
var e2MemberExpr2 = (callExpr2.Arguments[1] as LambdaExpression).Body as MemberExpression;
ans.Add(e2MemberExpr2.Member.Name);
var e1MemberExpr1 = (callExpr1.Arguments[1] as LambdaExpression).Body as MemberExpression;
ans.Add(e1MemberExpr1.Member.Name);
return ans;
}