2011-04-11 62 views
1

在我的代碼中,我需要通過價格Rating.TotalGrade對收集進行排序,正如您可以看到兩個LINQ查詢幾乎是相同的語句,只有很小的差異。在LINQ謂詞中使用OrderBy?

我想使用LINQ的謂詞代替但你可以看到在排序依據的主要區別是,我發現使用排序依據在查詢中沒有樣品。是否有可能或有其他方法來縮短我的代碼,也許未來會有更多的條件。

if (CurrentDisplayMode == CRSChartRankingGraphDisplayMode.Position) 
{ 
    this.collectionCompleteSorted = new List<Result>(from co in collection 
            where co.IsVirtual == false 
            orderby co.Price, co.CurrentRanking 
            select co); 
} 
else if (CurrentDisplayMode == CRSChartRankingGraphDisplayMode.Grade) 
{ 
    this.collectionCompleteSorted = new List<Result>(from co in collection 
            where co.IsVirtual == false 
            orderby co.Rating.TotalGrade, co.CurrentRanking 
            select co); 
} 

回答

2

您可以輕鬆地使用LINQ的遞延性質和輕鬆撰寫查詢的能力。

可能使用這樣的代碼:

 var baseQuery = from co in collection where !co.IsVirtual select co; // base of query 
     IOrderedEnumerable<Result> orderedQuery; // result of first ordering, must be of this type, so we are able to call ThenBy 

     switch(CurrentDisplayMode) // use enum here 
     { // primary ordering based on enum 
      case CRSChartRankingGraphDisplayMode.Position: orderedQuery = baseQuery.OrderBy(co => co.Price); 
       break; 
      case CRSChartRankingGraphDisplayMode.Grade: orderedQuery = baseQuery.OrderBy(co => co.TotalGrade); 
       break; 
     } 

     this.collectionCompleteSorted = orderedQuery.ThenBy(co => co.CurrentRanking).ToList(); // secondary ordering and conversion to list 

它很容易理解和避免轉換,列出,直到最後一刻。

+0

完美的作品!謝謝!早期轉變爲列出壞事? – TalkingCode 2011-04-12 09:07:00

+0

它還不錯。但是如果你太早轉換爲List,你不能使用ThenBy進行二級排序。另外,如果您使用Linq to SQL或Entities,那麼這將導致查詢完全轉換爲SQL。如果您提前轉換爲列表,則會在客戶端完成排序。 – Euphoric 2011-04-12 09:46:54

1

如果只您的訂單由不同的是,不是你的返回結果爲this.collectionCompleteSorted,然後做this.collectionCompleteSorted.OrderBy()當您通過數據枚舉。

this.collectionCompleteSorted = new List<Result>(from co in collection 
                  where co.IsVirtual == false                 
                  select co); 

foreach (var obj in this.collectionCompleteSorted.OrderBy(c => c.Price).ToList()) 
{ 
    // do something 
} 

並刪除您的當前linq查詢命令。

如果查詢只執行一次,那麼可以在上例中的linq查詢中省略.ToList()。當ToList被調用時,這將導致查詢立即執行,如果OrderBy在以後對集合的調用中實現並且ToList也是實現的,那麼查詢實際上將在具有order by語句的數據庫服務器上執行,將代碼的排序從代碼卸載到數據庫。請參閱http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx

+0

-1根本不回答問題 – Euphoric 2011-04-11 16:06:21

+0

@Euphoric你在說什麼?問題是關於如何避免不在linq查詢中下訂單。我說過在集合上使用OrderBy方法調用,奇怪的是你要在下面做同樣的事情。 – mservidio 2011-04-11 16:18:44

+0

那麼,基於枚舉值的不同排序的變化在哪裏?隨着二次訂購。 – Euphoric 2011-04-11 16:31:13

1

爲什麼不只是獲取值(少排序),然後(看起來)使用一個大小寫來排序結果?

// build your collection first 
var items = from co in collection 
      where !co.IsVirtual 
      select co; 

// go through your sort selectors 
select (CurrentDisplayMode) 
{ 
    case CRSChartRankingGraphDisplayMode.Position: 
    this.collectionCompleteSorted = items.OrderBy(i => i.Price).ThenBy(j => j.CurrentRanking).ToList(); 
    break; 
    case CRSChartRankingGraphDisplayMode.Grade: 
    this.collectionCompleteSorted = items.OrderBy(i => i.TotalGrade).ThenBy(j => j.CurrentRanking).ToList(); 
    break; 
    ... 
    //default: // maybe you want this, too 
} 
+0

幾乎在那裏,我會建議從basequery中刪除ToList,並在orderby之後執行toList。 此外,你必須保存你的OrderBy的結果再次在成員,即:this.collectionCompleteSorted = this.collectionCompleteSorted.OrderBy(...)。ThenBy(...) – Polity 2011-04-11 15:30:03

+0

@Polity:同意。我發了一個提交,仍然在編寫代碼。 ;-) Uno紀念品,por。 ; p – 2011-04-11 15:31:16

1
var q = collection.Where(co => !co.IsVirtual); 

if (CurrentDisplayMode == CRSChartRankingGraphDisplayMode.Position) 
{ 
    q = q.OrderBy(co => co.Price).ThenBy(co => co.CurrentRanking); 
} 
else if (CurrentDisplayMode == CRSChartRankingGraphDisplayMode.Grade) 
{ 
    q = q.OrderBy(co => co.Rating.TotalGrade).ThenBy(co => co.CurrentRanking); 
} 

this.collectionCompleteSorted = q.ToList(); 
+0

你不能在q上調用ThenBy,因爲q將被推斷爲廣告IEnumerable <>而不是IOrderedEnumerable <> – Euphoric 2011-04-11 15:46:31

+0

@Euphoric,你是對的,編輯。 – Equiso 2011-04-11 16:23:08