NHibernate ¿Cómo seleccionar objetos distintos según una propiedad específica mediante HQL?

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

  •  05-07-2019
  •  | 
  •  

Pregunta

¿Cómo se puede usar HQL para seleccionar objetos específicos que cumplen con ciertos criterios?

Hemos intentado lo siguiente para generar una lista de los diez principales canales RSS suscritos (donde SubscriptionCount es una propiedad derivada):

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

Donde la intención es solo seleccionar las dos URL de feed únicas en la base de datos, en lugar de las diez filas en la base de datos instanciadas como objetos. El resultado de lo anterior es:

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.

¿Es posible simplemente diluir los resultados para que saquemos las dos URL de fuentes únicas después de que obtengamos los datos de la base de datos, pero debe haber una forma de hacerlo a nivel de base de datos utilizando HQL?

EDITAR: nos damos cuenta de que es posible realizar una consulta escalar y luego extraer valores manualmente, pero ¿no hay una manera de simplemente especificar un criterio de coincidencia para los objetos retirados?

¿Fue útil?

Solución

Si cambias un poco tu HQL para que se vea así:

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 variable topTen será un objeto [] con 2 elementos en los que habrá 2 URL de feed.

Puede devolver esto como una colección fuertemente tipada si usa el método SetResultTransformer () de la interfase IQuery.

Otros consejos

Debe realizar una consulta escalar. Aquí hay un ejemplo de los documentos de 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];
    .....
}

Es el grupo por rss.FeedUrl lo que le está causando el problema. No parece que lo necesites, ya que estás seleccionando las entidades mismas. Quita eso y creo que estarás bien.

EDITAR - Mis disculpas no noté la parte sobre la "propiedad derivada". Por lo que supongo que quiere decir que no es una propiedad asignada a Hibernate y, por lo tanto, ¿no tiene realmente una columna en la tabla? Eso explicaría el segundo mensaje de error que recibió en su consulta. Es posible que deba eliminar la orden " por " cláusula también y haga su clasificación en Java si ese es el caso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top