2010-04-08 5 views
5

Ich mag würde mein Ergebnis so sortieren:Sortieren nach null/nicht null mit ICriteria

  • Zuerst möchte ich alle Zeilen/Objekte, bei denen eine Spalte/Eigenschaft nicht null ist, dann werden alle, wo der colmn/property ist null.
  • Dann möchte ich nach einer anderen Spalte/Eigenschaft sortieren.

Wie kann ich dies mit ICriteria tun? Muss ich meine eigene Order-Klasse erstellen, oder kann das mit vorhandenem Code geschehen?

ICriteria criteria = Session.CreateCriteria<MyClass>() 
    .AddOrder(Order.Desc("NullableProperty")) // What do I do here? IProjection? Custom Order class? 
    .AddOrder(Order.Asc("OtherProperty")); 

Ich möchte einen Auftrag wie diese haben:

NullableProperty OtherProperty 
---------------- ------------- 
1     2 
8     7 
5     9 
NULL    1 
NULL    3 
NULL    8 

Antwort

11

Ich habe endlich eine funktionierende Antwort dafür. Ich habe es nicht möglich war, vor (10k ist meine Antwort gelöscht sehen), aber ich mit einer SQL-Abfrage gestartet:

SELECT Id, NullableProperty, OtherProperty 
    FROM NullableSorting 
    ORDER BY 
     (CASE WHEN NullableProperty IS NULL THEN 1 ELSE 0 END), 
     OtherProperty 

und dann konvertiert die Kriterien Schnittstellen zu verwenden. Alle hier verwendeten Objekte sind eingebaut.

ICriteria criteria = 
    session.CreateCriteria(typeof(NullableEntity)) 
    .AddOrder 
    (
     Order.Asc 
     (
      Projections.Conditional 
      (
       Restrictions.IsNull("NullableProperty"), 
       Projections.Constant(1), 
       Projections.Constant(0) 
      ) 
     ) 
    ) 
    .AddOrder(Order.Asc("OtherProperty")); 
+0

In meinem Fall wollte ich Nullen zuletzt, aber immer noch von NullableProperty für die Nicht-Null-Werte bestellen. Dies ist jedoch eine gute Antwort, die mich zu 99% dorthin geführt hat. Für alle anderen, die das gleiche wollen, fügen Sie einfach '.AddOrder (Order.Asc (" NullableProperty ")' nach der Groß-/Kleinschreibung hinzu, aber vor OtherProperty. –

0

Ich weiß nichts über ICriteria, aber hier ist ein Gedanke. Sie könnten versuchen, benutzerdefiniertes SQL zum Laden zu verwenden - mit anderen Worten, einen <sql-query> Block in Ihrem Mapping, der Ihnen eine sortierbare Spalte bietet. In Oracle wäre es etwa so:

<sql-query ...> 
    <return ...> 
    select *, nvl2(my_column, 1, 0) as not_null 
    from my_table 
    where id=? 
    for update 
</sql-query>