NHibernate Come selezionare oggetti distinti in base a proprietà specifiche utilizzando HQL?

StackOverflow https://stackoverflow.com/questions/1800289

  •  05-07-2019
  •  | 
  •  

Domanda

Come si può utilizzare HQL per selezionare oggetti specifici che soddisfano determinati criteri?

Abbiamo provato quanto segue per generare un elenco dei primi dieci feed RSS sottoscritti (in cui SubscriptionCount è una proprietà derivata):

var topTen = UoW.Session.CreateQuery( @"SELECT distinct rss 
                                                 FROM RssFeedSubscription rss
                                                 group by rss.FeedUrl
                                                 order by rss.SubscriptionCount DESC
                                                 ")
.SetMaxResults(10)
.List<RssFeedSubscription>();

Dove l'intenzione è solo quella di selezionare i due URL di feed univoci nel database, anziché le dieci righe nel database istanziate come oggetti. Il risultato di cui sopra è:

Column 'RssSubscriptions.Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.

È possibile assottigliare i risultati in modo da eliminare i due URL di feed univoci dopo aver recuperato i dati dal database, ma deve esserci un modo per farlo a livello di DB usando HQL?

EDIT: ci rendiamo conto che è possibile eseguire una query scalare e quindi estrarre manualmente i valori, ma non esiste un modo per specificare semplicemente un criterio di corrispondenza per gli oggetti ritirati?

È stato utile?

Soluzione

Se cambi un po 'il tuo HQL in questo modo:

var topTen = UoW.Session.CreateQuery( @"SELECT distinct rss.FeedUrl
                                          FROM RssFeedSubscription rss
                                          group by rss.FeedUrl
                                          order by rss.SubscriptionCount DESC
                                        ")
.SetMaxResults(10)
.List();

la variabile topTen sarà un oggetto [] con 2 elementi in cui ci sono i 2 URL dei feed.

Puoi restituirlo come raccolta fortemente tipizzata se usi il metodo SetResultTransformer () dell'interfaccia IQuery.

Altri suggerimenti

È necessario eseguire una query scalare. Ecco un esempio dai documenti di NHibernate:

IEnumerable results = sess.Enumerable(
    "select cat.Color, min(cat.Birthdate), count(cat) from Cat cat " +
    "group by cat.Color"
);
foreach ( object[] row in results )
{
    Color type = (Color) row[0];
    DateTime oldest = (DateTime) row[1];
    int count = (int) row[2];
    .....
}

È il gruppo di rss.FeedUrl a causare il problema. Non sembra che tu ne abbia bisogno poiché stai selezionando le entità stesse. Rimuovilo e penso che sarai bravo.

MODIFICA - Mi scuso non ho notato la parte relativa alla "proprietà derivata". Con ciò suppongo che intendi che non è una proprietà mappata con Hibernate e, quindi, in realtà non ha una colonna nella tabella? Ciò spiegherebbe il secondo messaggio di errore che hai ricevuto nella tua query. Potrebbe essere necessario rimuovere " ordina per " anche la clausola e, se è il caso, esegui l'ordinamento in Java.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top