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容易得多,所以如果你的应用中没有太多的枚举比较,使用它可能会更好。 –