0
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<TModel, TMember>>(memberAccess, param);

对于 Employee.Job.Salary 的成员访问,这相当于什么?

4

2 回答 2

10

你需要:

var jobProperty = Expression.PropertyOrField(param, "Job");
var salaryProperty = Expression.PropertyOrField(jobProperty, "Salary");

基本上,您是Salary从评估结果中获取属性x.Job

如果您需要以编程方式执行此操作,则需要以下内容:

Expression expression = Expression.Parameter(type, "x");
foreach (var property in properties.Split('.'))
{
    expression = Expression.PropertyOrField(expression, property);
}
于 2012-06-23T08:25:24.553 回答
-1

最好的方法是在这里创建扩展:

public static class ExpressionExtensions
{
    /// <summary>
    ///     create expression by property name
    /// </summary>
    /// <typeparam name="TModel"></typeparam>
    /// <param name="propertyName">
    ///     <example>Urer.Role.Name</example>
    /// </param>
    /// <returns></returns>
    public static Expression<Func<TModel, dynamic>> CreateExpression<TModel>(this string propertyName) {
        Type currentType = typeof (TModel);
        ParameterExpression parameter = Expression.Parameter(currentType, "x");
        Expression expression = parameter;

        int i = 0;
        List<string> 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<Func<TModel, dynamic>>(expression, parameter);
    }
}

您不能每次都将 Convert() 转换为 typeof(object),因为 System.Object 没有您的类型所具有的属性(例如您的示例中的 Name 或 Salary)。

于 2014-07-22T13:45:22.103 回答