3

我有以下排序表达式:

this.Students = this.Students.OrderBy(x => x.ExamData.OrderByDescending(p => p.ExamDate).ThenByDescending(p => p.ExamId).FirstOrDefault().TotalMarks);

虽然我的想法是将表达式抽象为

x => x.ExamData.OrderByDescending(p => p.ExamDate).ThenByDescending(
                                  p => p.ExamId).FirstOrDefault().TotalMarks

制作为 lambda 表达式,以便我可以使用 like

this.Students = this.Students.OrderBy(sortExpression);

这是因为我有很多排序字段,例如上面定义的 TotalMarks,我只想从排序字段创建表达式,然后调用 OrderBy。

我从这个链接知道,我们可以创建一个使用子属性的表达式,但不能使用内部表达式。

目前我已经给出了一个开关盒并在每种情况下都写了相同的东西,比如

this.Students = this.Students.OrderBy(x => x.ExamData.OrderByDescending(p => p.ExamDate).ThenByDescending(p => p.ExamId).FirstOrDefault().SubjectName);

所以我的想法是使用静态方法创建 kindof ExpressionBuilder,该方法构建传递 fieldName 的表达式,例如

public static Expression BuildSortExpression(string fieldName) {}
4

3 回答 3

1

您可以轻松地将大部分逻辑提取到方法中:

private int sortExpression(Student x) { 
    return x.ExamData.OrderByDescending(p => p.ExamDate).ThenByDescending(p => p.ExamId).FirstOrDefault().TotalMarks;
}

假设TotalMarks是一个int.

然后你只需要使用:

this.Students.OrderBy(x => sortExpression(x));

或将其添加为 Student 的属性。

警告:如果您将它与 ORM(linq to SQL、实体框架等)一起使用,它的执行效率将不如前面的代码!

于 2013-02-20T18:29:16.453 回答
1

尝试创建一个可重用的表达式变量最终将比仅仅创建自己的扩展方法来完成整个排序需要更多的工作:

public static IQueryable<Student> OrderByMarks(this IQueryable<Student> students)
{
    return students.OrderBy(student => student.ExamData
        .OrderByDescending(exam => exam.ExamDate)
        .ThenBy(exam => exam.ExamId)
        .FirstOrDefault().TotalMarks);
}

然后你可以像这样使用它:

this.Students = this.Students.OrderByMarks();
于 2013-02-20T18:33:05.447 回答
-1

使用 Ben 的想法得到了解决方案。创建了一个

Dictionary<string, Func<Student, Object>>

以排序字段为键,函数为

new Func<Student, object>((Student student) => { return GetLatestExam(student).TotalMarks; })

而 GetLatestExam 静态方法为

private static Study GetLatestExam(Student student)
{
     return student.ExamData.OrderByDescending(p => p.ExamDate).ThenByDescending(p => p.ExamId).FirstOrDefault();
}

然后在实际排序中,我只需要这样调用:

public void Sort(string sortField, bool sortAscending)
{
     // based on the sort field, get the sorting expression and execute.
     if(sortAscending)
     {
          this.Students= this.Students.OrderBy(student=>this._customSortColumns[sortField](student));
     }
     else
     {
          this.Patients = this.Patients.OrderByDescending(student=>this._customSortColumns[sortField](student));
     }
}
于 2013-02-20T21:11:55.943 回答