具有内部表达式的OrderBy linq的表达式

时间:2013-02-20 18:18:53

标签: c# linq lambda

我对排序有以下表达:

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表达式,以便我可以像

一样使用
this.Students = this.Students.OrderBy(sortExpression);

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

我从这个link知道,我们可以创建一个表达式,其中使用了child属性,但没有使用内部表达式。

目前我已经给出了一个开关案例并在每种情况下都写了相同的内容,如

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

所以我的想法是用一个静态方法创建一个ExpressionBuilder,它构建传递给fieldName的表达式,比如

public static Expression BuildSortExpression(string fieldName) {}

3 个答案:

答案 0 :(得分:1)

您可以轻松地将大部分逻辑转换为方法:

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

假设TotalMarksint

然后你只需要使用:

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

或将其添加为学生的财产。

警告: 如果你使用ORM(linq to SQL,Entity framework等),这将不会像以前的代码一样有效执行!

答案 1 :(得分: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();

答案 2 :(得分:-1)

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

Dictionary<string, Func<Student, Object>>

将sort字段作为键,将func作为

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