LINQ委托Lambda Select语句绑定子属性

时间:2015-05-26 06:46:34

标签: c# linq

我正在为LINQ中的Select语句创建委托。一些属性绑定是我选择的对象上的子属性。

这是我想要放在我的代理中的LINQ语句:

var list = dataSet.Select(x => new ViewModel()
{
    Name = x.Name,
    ClassType = x.ClassType.Description
};

我可以让Name无需担心我的代码,但我不知道如何获取ClassType.Description

这是我目前的代码:

protected Func<Student, ManagerStudentListViewModel> GetSelectStatement()
{
    var studentType = typeof(Student);
    var viewModelType = typeof(ManagerStudentListViewModel);
    var parameterExpression = Expression.Parameter(studentType, "x");
    var newInstantiationExpression = Expression.New(viewModelType);

    // Name Binding
    var viewModelProperty = viewModelType.GetProperty("Name");
    var studentProperty = studentType.GetProperty("Name");
    var nameMemberExpression = Expression.Property(parameterExpression, studentProperty);
    var nameBinding = Expression.Bind(viewModelProperty, nameMemberExpression);

    // ClassType.Description Binding
    // ???

    var bindings = new List<MemberAssignment>() { nameBinding, classTypeBinding  };
    var memberInitExpression = Expression.MemberInit(newInstantiationExpression, bindings);
    var lambda = Expression.Lambda<Func<Student, ManagerStudentListViewModel>>(memberInitExpression, parameterExpression);
    return lambda.Compile();
}

1 个答案:

答案 0 :(得分:1)

访问深层嵌套的成员与访问任何其他属性没有什么不同,只要您知道成员的名称即可。只需创建一个表达式来获取第一个属性,然后添加表达式以获得第二个属性。

Expression<Func<Student, ManagerStudentListViewModel>> GetSelectStatement()
{
    var studentType = typeof(Student);
    var viewModelType = typeof(ManagerStudentListViewModel);

    var param = Expression.Parameter(studentType, "x");
    var nameValue = Expression.Property(param, "Name");
    var classTypeValue = Expression.Property(
            Expression.Property(param, "ClassType"), // get the class type
            "Description"); // get the description of the class type

    var nameMemberBinding = Expression.Bind(
            viewModelType.GetProperty("Name"),
            nameValue);
    var classTypeMemberBinding = Expression.Bind(
            viewModelType.GetProperty("ClassType"),
            classTypeValue);
    var initializer = Expression.MemberInit(
            Expression.New(viewModelType),
            nameMemberBinding,
            classTypeMemberBinding);
    return Expression.Lambda<Func<Student, ManagerStudentListViewModel>>(initializer, param);
}