2011-08-08 95 views
1

我查詢Order元素與LINQ(C#)的表。每個訂單都有以下字段:LINQ - 複雜的排序

- ID 
- OpenDate 
- PriorityID 
- StatusID 
- Description 

StatusID字段映射到狀態表。狀態表的結構爲:

- ID 
- Name 

我需要獲取按優先級和狀態排序的所有Order對象。 我可以成功獲取按優先級排序的Order對象。我通過 下面這樣:

List<Order> orders = new List<Order>(); 
using (DBDataContext context = new DBDataContext()) 
{ 
    orders = (from o in context.Orders 
      orderby (o.PriorityID.HasValue ? o.PriorityID : Int32.MaxValue) ascending 
      select o).ToList(); 
} 

但我的問題是在狀態融通。

一旦訂單對象按優先級排序,我需要按以下狀態順序對訂單對象 進行排序:已取消,已打開,正在路由和已遞送。值得注意的是,這些「狀態」值的ID以固定的隨機順序固定設置。我無法改變它們。正如你所看到的,我無法通過alphbetical的名字來排序。另外,我不能將任何字段添加到我的數據庫中。任何人都可以告訴我如何在LINQ中解決這個問題?

謝謝!

+1

你是否也在頂部(Take)在這裏?我想知道是否需要在數據庫中完成,或者是否可以在.NET代碼中進行排序...... –

+0

是的,需要對多少項進行排序?如果你可以做到客戶端,那麼IComparer或比較委託'List.OrderBy(x,y => ...)'會很多。 –

+0

您可以在前端爲您的訂單類添加計算字段嗎?然後你可以按照該字段排序。例如:「select new {SortField =在此計算排序索引}」。 – Andrei

回答

2

我認爲你必須解決這個通過實現IComparer並使用Linq來訂購它。由於您的狀態不是數字或字母順序。

public class CustomComparer : IComparer<Status> 
{ 
    public int Compare(Status statusA, Status statusB) 
    { 
     if (statusA.StatusName == "Cancelled" && statusB.StatusName == "Cancelled") 
     { 
      return 0; // equals 
     } 
     else if (statusA.StatusName == "Cancelled" && statusB.StatusName != "Cancelled") 
     { 
      return 1; // A > B 
     } 
     .... 
    } 
} 

然後

orders.OrderBy(x => x.Status, new CustomComparer()) 

希望這有助於。

+0

我會放置一個switch-case語句而不是ifs,因爲序列順序非常具體,可能會更改或者稍後添加新項目。 – Andrei

+0

我喜歡這種方法。然而,我現在得到一個「不支持的重載用於查詢運算符'ThenBy'」錯誤,當我運行以下行:var results = context.Orders.OrderBy(p => p.PriorityID Int32.MaxValue).ThenBy(s => s.StatusID,new CustomComparer())。ToList(); – user609886

+0

可能因爲不能表達爲SQL。您緩存數組中的訂單,然後您應該能夠應用排序(儘管出於性能原因可能不實用) – FuleSnabel

0

只要狀態列表保持一致,您可以創建一個字符串,例如「COID」,並根據「COID」.indexOf(firstletterofstatus)比較兩個狀態。也許不是最好的軟件實踐,但它會工作。

-1

如果它不會很長的列表(即它會相當適合在內存中),你可以進行排序與​​狀態和相對定單之間的映射客戶端:

int StatusOrder(Status status) 
{ 
    switch(status.Id) 
    { 
     case 1: return 5; 
     case 2: return 1; 
     case 4: return 3; 
     //etc 
    } 
} 

List<Order> orders; //no need to create a list here 
using (DBDataContext context = new DBDataContext()) 
{ 
    orders = (from o in context.Orders 
     orderby (o.PriorityID.HasValue ? o.PriorityID : Int32.MaxValue) ascending, 
       SorderOrder(o.Status) 
     select o).ToList(); 
} 
+0

-1:將提供運行時異常,因爲它無法將'StatusOrder'轉換爲SQL。 –