2013-02-20 141 views
3

expresssion:表達式的OrderBy LINQ與內表達

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

雖然我的想法是抽象能夠製成一個lambda表達式使得表達爲

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

我可以使用像

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

這是因爲我有很多排序字段,如TotalMarks定義d,我想從排序字段創建表達式,然後調用OrderBy。

我知道從這個link,我們可以創建一個表達式,使用子屬性,但沒有得到內部表達式。

目前,我已經給了一個開關的情況下,寫同樣的東西在每種情況下像

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

所以我的想法是創建kindof的ExpressionBuilder與構建傳遞的字段名錶達的靜態方法,像

public static Expression BuildSortExpression(string fieldName) {} 

回答

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等),這將不會像以前的代碼那樣高效執行!

+0

Th在EF不會正確轉換。 – Servy 2013-02-20 18:29:42

+0

好點,雖然在問題中沒有提到EF,所以我認爲這是一個直接的枚舉,但我會更新這個問題。 – Ben 2013-02-20 18:32:21

+1

他指的是'Expression',它告訴我們這是一個IQueryable。它可能是一些其他的提供者,比如Linq to SQL,它可以支持這一點,但EF至少是一個可能的選擇。 – Servy 2013-02-20 18:34:05

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(); 
+0

但是它現在正在做同樣的事情,因爲我將不得不爲每個屬性(字段名稱)創建方法,這對於我來說是最不可能的選擇。 – Chinjoo 2013-02-20 18:45:22

-1

用Ben的想法得到了一個解決方案。 創建一個

Dictionary<string, Func<Student, Object>> 

與排序字段作爲鍵和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)); 
    } 
} 
+0

這是一個LINQ to object解決方案,但OP正在使用查詢提供程序。 – Servy 2013-02-20 21:13:58