深度> 1的成员访问的表达式树
public class Job { public string Name { get; set; } public int Salary { get; set; } } public class Employee { public string Name { get; set; } public Job Job { get; set; } }
如果我想创建一个成员访问Employee.Name的表达式树,这就是我所做的:
var param = Expression.Parameter(type, "x"); var memberAccess = Expression.PropertyOrField(param, memberName); return Expression.Lambda<Func>(memberAccess, param);
对Employee.Job.Salary的成员访问权限相当于什么?
你需要:
var jobProperty = Expression.PropertyOrField(param, "Job"); var salaryProperty = Expression.PropertyOrField(jobProperty, "Salary");
基本上你从评估x.Job
的结果中获取Salary
属性。
如果您需要以编程方式执行此操作,则需要以下内容:
Expression expression = Expression.Parameter(type, "x"); foreach (var property in properties.Split('.')) { expression = Expression.PropertyOrField(expression, property); }
最好的方法是创建扩展, 如下所示 :
public static class ExpressionExtensions { /// /// create expression by property name /// /// /// /// Urer.Role.Name /// /// public static Expression> CreateExpression(this string propertyName) { Type currentType = typeof (TModel); ParameterExpression parameter = Expression.Parameter(currentType, "x"); Expression expression = parameter; int i = 0; List propertyChain = propertyName.Split('.').ToList(); do { System.Reflection.PropertyInfo propertyInfo = currentType.GetProperty(propertyChain[i]); currentType = propertyInfo.PropertyType; i++; if (propertyChain.Count == i) { currentType = typeof (object); } expression = Expression.Convert(Expression.PropertyOrField(expression, propertyInfo.Name), currentType); } while (propertyChain.Count > i); return Expression.Lambda>(expression, parameter); } }
你不能每次都将Convert()转换为typeof(object),因为System.Object没有你的类型所具有的属性(例如你的名字或Salary)。