LINQ Delegate Lambda Select Statement Bind Child Property

本文关键字:Bind Child Property Statement Select Delegate Lambda LINQ | 更新日期: 2023-09-27 17:50:51

我正在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();
}

LINQ Delegate Lambda Select Statement Bind Child Property

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

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);
}