web-dev-qa-db-fra.com

Obtenez un résultat distinct de NHibernate en utilisant des critères API?

J'essaie d'obtenir des résultats distincts en utilisant l'API de critères dans NHibernate. Je sais que cela est possible en utilisant HQL, mais je préférerais procéder à cela à l'aide de l'API de critère, car le reste de mon application est écrit en utilisant uniquement cette méthode. I a trouvé ce post du forum , mais je n'ai pas pu le faire fonctionner. Existe-t-il un moyen avec l'API de critères pour obtenir des ensembles de résultats distincts?

Edit: En faisant cela, je voulais également exclure la colonne principale clé, qui est également une identité et obtenez les enregistrements distincts restants. Y a-t-il un moyen de faire cela? Comme c'est le cas, les enregistrements distincts renvoient des doublons car la clé primaire est unique pour chaque ligne, mais tous les autres champs sont les mêmes.

29
Mark Struzinski

Vous ne pouvez pas voir le poste de forum en ce moment (lien brisé?), Alors peut-être que ce n'est peut-être pas la réponse, mais vous pouvez ajouter un distinctrooTentitityResultTransformer:

session.CreateCriteria(typeof(Product)
    .Add(...)
    .SetResultTransformer(new DistinctEntityRootTransformer())
25
Juanma

Pour effectuer une requête distincte, vous pouvez définir la projection sur les critères des projections.Distinct. Vous incluez ensuite les colonnes que vous souhaitez revenir. Le résultat est ensuite retourné en un objet fortement typé en réglant le transformateur de résultat en aliastobeansultTransformer - en passant dans le type que le résultat doit être transformé en. Dans cet exemple, j'utilise le même type que l'entité elle-même, mais vous pouvez créer une autre classe spécifiquement pour cette requête.

ICriteria criteria = session.CreateCriteria(typeof(Person));
criteria.SetProjection(
    Projections.Distinct(Projections.ProjectionList()
        .Add(Projections.Alias(Projections.Property("FirstName"), "FirstName"))
        .Add(Projections.Alias(Projections.Property("LastName"), "LastName"))));

criteria.SetResultTransformer(
    new NHibernate.Transform.AliasToBeanResultTransformer(typeof(Person)));

IList<Person> people = criteria.List<Person>();

Cela crée SQL similaire à (dans SQL Server au moins):

SELECT DISTINCT FirstName, LastName from Person

Sachez que seules les propriétés que vous spécifiez dans votre projection seront renseignées dans le résultat.

L'avantage de cette méthode est que le filtrage est effectué dans la base de données plutôt que de renvoyer tous les résultats à votre application, puis effectuez le filtrage - qui est le comportement de distinctrooTentityTransformer.

89
Aidan Boyle

Pour ce que cela vaut, NHibernate: optimiser les requêtes avec les projections m'a aidé avec fondamentalement ce même problème.

6
Jon Adams