NHibernate Comment sélectionner des objets distincts en fonction de propriétés spécifiques en utilisant HQL?

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

  •  05-07-2019
  •  | 
  •  

Question

Comment utiliser HQL pour sélectionner des objets spécifiques répondant à certains critères?

Nous avons essayé ce qui suit pour générer une liste des dix principaux flux RSS abonnés (où SubscriptionCount est une propriété dérivée):

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

Où l'intention est uniquement de sélectionner les deux URL uniques de flux dans la base de données, plutôt que les dix lignes de la base de données instanciées en tant qu'objets. Le résultat de ce qui précède est:

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.

Il est possible simplement d’affiner les résultats afin de supprimer les deux URL de flux uniques après avoir récupéré les données de la base de données, mais il doit y avoir un moyen de le faire au niveau de la base de données en utilisant HQL?

EDIT: Nous réalisons qu’il est possible de faire une requête Scalar puis d’extraire manuellement les valeurs, mais n’est-il pas possible de spécifier simplement un critère de correspondance pour les objets extraits?

Était-ce utile?

La solution

Si vous changez un peu votre HQL pour ressembler à cela:

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 sera un objet [] avec 2 éléments dans les 2 URL de flux.

Vous pouvez avoir cette collection renvoyée en tant que collection fortement typée si vous utilisez la méthode SetResultTransformer () de l'interface IQuery.

Autres conseils

Vous devez effectuer une requête scalaire. Voici un exemple tiré de la documentation 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];
    .....
}

C'est le groupe de rss.FeedUrl qui vous pose problème. Il ne semble pas que vous en ayez besoin puisque vous sélectionnez les entités elles-mêmes. Supprimez cela et je pense que vous serez bon.

EDIT - Mes excuses, je n’ai pas remarqué la partie concernant la "propriété dérivée". Par là, je suppose que vous voulez dire que ce n’est pas une propriété mappée par Hibernate et qu’elle n’a donc pas de colonne dans la table? Cela expliquerait le deuxième message d'erreur que vous avez reçu dans votre requête. Vous devrez peut-être supprimer la commande "Commande par". clause aussi bien et faites votre tri en Java si c'est le cas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top