2009-04-14 8 views
6

Si consideri la seguente query criteri:Case-insensitive sorta ordinamento in NHibernate

var x = SomeCriteria.AddOrder (nuovo Ordine ("Nome", true)) Lista();.

Ciò ordinare il set di risultati dalla proprietà Name, ma tra maiuscole e minuscole:

"A1" 
"B1" 
"a2" 

Delle idee come aggiungere il caso ordine insensitive così risultare "a2" finirà prima "B1"?

risposta

10

Dovresti riuscire a farlo ordinando una proiezione che normalizzi il caso. Ad esempio, Oracle ha una funzione "inferiore" che riduce i tipi di dati stringa stringa come varchar2 e nvarchar2; quindi userò questa funzione sql per formare una proiezione che ordinerà in modo appropriato.

 
var projection = Projections.SqlFunction("lower", 
             NHibernateUtil.String, 
             Projections.Property("Name")); 

var x = SomeCriteria.AddOrder(Orders.Asc(projection)).List() 

Se si utilizza SQL Server, si consiglia di utilizzare la funzione "superiore" anziché "inferiore" per l'efficienza. Microsoft ha ottimizzato il suo codice nativo per l'esecuzione di confronti maiuscoli, in cui il resto del mondo sembra aver ottimizzato le lettere minuscole.

+0

+1 per la nota sull'ottimizzazione "superiore" di SQL Server;) grazie. –

+0

Questo è fantastico. Tuttavia, quando eseguo l'ordinamento in una griglia, non conosco il tipo di colonna. Sai se posso in qualche modo rilevare il tipo di colonna e applicare solo questa proiezione alle stringhe? – Mac

2

Hibernate (Java) ha un metodo "ignoreCase()" nella classe "Ordine", ma sembra che NHibernate non abbia questo metodo sul suo "Ordine".

Questo è come pensavo si potesse fare:

var x = SomeCriteria.AddOrder(new Order("Name", true).IgnoreCase()).List(); 

Ma, purtroppo, non c'è IgnoreCase().

Per ovviare al problema, è possibile utilizzare una query HQL o SQL: una di queste dovrebbe consentire di ordinare la distinzione tra maiuscole e minuscole.

+0

Nel frattempo questo funziona in NHibernate :-) –

2

Questo probabilmente dipende dall'impostazione di distinzione tra maiuscole e minuscole sul server del database. Sospetto che NHibernate emetta solo una clausola "ORDER BY"; almeno, non riesco a immaginare cos'altro farebbe. Per SQL Server, l'ordinamento predefinito (confronto) è l'ordine del dizionario, senza distinzione tra maiuscole e minuscole.

This article fornisce alcune tecniche per l'esecuzione di ricerche sensibili al maiuscolo/minuscolo in SQL Server. Tuttavia, il mio consiglio è di ordinare l'elenco che viene restituito dalla query nel codice. Questa soluzione preserva l'indipendenza del database di NHibernate e consentiamo di personalizzare l'ordinamento in base alle proprie esigenze.

+1

-1 Stai seriamente suggerendo di saltare l'ordinamento db ottimizzato e utilizzare l'ordinamento nel codice? Hai testato tale soluzione nel sistema di produzione per le prestazioni? –

+0

Sì e sì. Hai? Senza ulteriori specificità nella domanda originale (RDBMS in uso, numero di righe previsto) è impossibile valutare il vantaggio dell'ordinamento nel codice (flessibile, dinamico, indipendente dal database) rispetto all'ordinamento sul server. L'indipendenza dal database è una ragione principale per l'utilizzo di un mappatore O/R e in genere vale la pena preservare in un'applicazione. –

0

Poiché so che le risposte alla mia query sono sempre abbastanza piccole, ho finito per interrogare i dati normalmente e ordinarli in seguito utilizzando Linq. Funziona, quindi perché preoccuparsi di modificare NHibernate;) (Utilizzo di SQLite, btw)