3

我有以下Enum它描述了項目和代表項目的對象的狀態。Linq to NHibernate OrderBy枚舉值

public Enum Status 
{ 
    Sent, 
    Received, 
    UnderWork, 
    Returned 
} 

public Class Item 
{ 
    public virtual int Id {get;set;} 
    public virtual Status CurrentStatus {get;set;} 
    public virtual string ItemDescription {get;set;} 
    public virtual int ItemNumber {get;set;} 
    public virtual DateTime DueDate {get;set;} 
} 

我需要創建一個查詢在那裏我可以選擇一些項目,責令先由CurrentStatus財產,其次是由於交貨期財產。難度是我想通過CurrentStatus進行排序,將所有具有返回狀態的項目放在最後,同時按照它們的DueDate排序,然後僅通過DueDate排序所有其他項目並忽略CurrentStatus。

所以下面的數據列表:

ID | CurrentStatus | ItemDescription | ItemNumber | DueDate 
------------------------------------------------------------- 
1 | Returned  | Description1 | 123456 | 16/01/2012 
2 | Sent   | Description2 | 234567 | 13/01/2012 
3 | Returned  | Description3 | 345678 | 22/01/2012 
4 | Received  | Description4 | 456789 | 03/01/2012 
5 | UnderWork  | Description5 | 567891 | 10/01/2012 
6 | UnderWork  | Description6 | 678901 | 17/01/2012 
7 | Sent   | Description7 | 789012 | 09/01/2012 
8 | Sent   | Description8 | 89| 28/01/2012 
9 | Returned  | Description9 | 9| 30/01/2012 
10 | Received  | Description10 || 15/01/2012 

使用會成纔像下面的LINQ to NHibernate的查詢(這是給我一個QuerySyntaxException:類型Antlr.Runtime.NoViableAltException「引發的異常。 )只要注意在LINQPad中使用這個表達式,我就可以得到我需要的結果。

var workList = session.Query<Item>() 
       .OrderBy(item => item.Status == Status.Returned) 
       .ThenBy(item => item.DueDate) 
       .ToList(); 

我期望得到的數據列表按以下順序:

ID | CurrentStatus | ItemDescription | ItemNumber | DueDate 
------------------------------------------------------------- 
4 | Received  | Description4 | 456789 | 03/01/2012 
7 | Sent   | Description7 | 789012 | 09/01/2012 
5 | UnderWork  | Description5 | 567891 | 10/01/2012 
2 | Sent   | Description2 | 234567 | 13/01/2012 
10 | Received  | Description10 || 15/01/2012 
6 | UnderWork  | Description6 | 678901 | 17/01/2012 
8 | Sent   | Description8 | 89| 28/01/2012 
1 | Returned  | Description1 | 123456 | 16/01/2012 
3 | Returned  | Description3 | 345678 | 22/01/2012 
9 | Returned  | Description9 | 9| 30/01/2012 

可以這樣使用LINQ to NHibernate的做什麼?如果是的話,我需要對我的查詢做些什麼改變?此外,我會期待SKip()和Take(),所以我不能從數據庫中取出所有東西。我使用SQL Server 2008 Express,NHibernate 3.3.0.4000和Fluent Nhibernate 1.3.0.727。

編輯

只是爲了闡述我多麼希望發生的排序。我希望返回狀態的項目被推到列表的底部,並按截止日期排序。我希望所有其他物品不會按狀態排序,並且只是到期日,因此它們總是會先於退回的物品。這是因爲返回的內容不再處於工作過程中,我希望它被推到列表的末尾。所以在這種情況下,返回以外的狀態值是不相關的。

回答

4

這對我有效。這是在NHibernate的應如何處理的狀態,並生成SQL語句case

var workList = session.Query<Item>() 
    .OrderBy(item => item.CurrentStatus == Status.Returned ? 1 : 0) 
    .ThenBy(item => item.DueDate) 
    .ToList(); 
+0

謝謝,它現在可以正常工作。再也不用把我的頭髮撕掉了! –

2

您的LINQ查詢似乎存在問題。不知道你是否按照意圖使用,但不應該有.OrderBy(item => item.Status)而不是.OrderBy(item => item.Status == Status.Returned)?這可能會混淆NHibernate的表達式解析器。

你是如何將你的枚舉映射到數據庫的?到int列(默認)?或者作爲一個字符串?

你能解釋一下預期的列表嗎?考慮到你是按狀態排序的,你不應該首先有Sent項目,然後Received,然後UnderWork和最後Returned?您預期的列表看起來沒有正確排序。

+0

我的排序應該如何工作的闡述更加明確,我希望這個澄清什麼,我希望發生的。我使用流暢的nhibernates自動映射,默認情況下將枚舉映射爲字符串。我同意它是.OrderBy(item => item.Status == Status.Returned),這是造成問題,但我不知道這個LINQ表達式是否只是不被支持,或者我可以改變,以得到我想要的地方。 –

+1

感謝您的澄清。我明白你現在想要達到的目標。猜猜NHibernate的解析器不是那麼聰明,但你可以讓它變得更聰明:http://www.primordialcode.com/blog/post/nhibernate-3-extending-linq-provider-fix-notsupportedexception –

+0

無論如何,西門子Echholt的答案似乎爲您的問題提供一個很好的解決方法。看起來比擴展NHibernate Linq容易得多,所以如果你的應用中沒有太多的枚舉比較,使用它可能會更好。 –