2010-04-08 18 views
5

me gustaría ordenar mi resultado como este:Ordenar por nulo/nulo no con ICriteria

  • En primer lugar quiero todas las filas/objetos en una columna/propiedad no es nulo, entonces todo donde el colmn/property es nulo.
  • Luego quiero ordenar por otra columna/propiedad.

¿Cómo puedo hacer esto con ICriteria? ¿Tengo que crear mi propia clase de pedido o puedo hacerlo con el código existente?

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

Me gustaría tener una orden como esta:

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

Respuesta

11

Finalmente tengo una respuesta funcional para esto. Yo no creía que fuera posible antes de 10k (pueden ver mi respuesta suprimido), pero empecé con una consulta SQL:

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

y luego convertidos al uso de las interfaces de criterios. Todos los objetos usados ​​aquí están incorporados.

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

En mi caso, quería que los valores nulos fueran los últimos, pero que NullableProperty sigue pidiendo los valores no nulos. Sin embargo, esta es una gran respuesta que me dio el 99% del camino hasta allí. Para cualquier otra persona que quiera lo mismo, simplemente agregue '.AddOrder (Order.Asc (" NullableProperty ")' después del pedido de casos pero antes de OtherProperty. –

0

no sé nada acerca de ICriteria, pero aquí es un pensamiento. Podría intentar usar SQL personalizado para cargar, en otras palabras, un bloque <sql-query> en su mapeo que le proporciona una columna ordenable. En Oracle sería algo como esto:

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