Obtenga un conjunto de resultados distinto de NHibernate utilizando Criteria API?


Estoy tratando de obtener resultados distintos utilizando la API de criterios en NHibernate. Sé que esto es posible usando HQL, pero preferiría hacerlo usando la API de Criterios, porque el resto de mi aplicación está escrita usando solo este método. Yo encontré esta publicación en el foro, pero no he podido hacer que funcione. ¿Hay alguna manera con la API de criterios para obtener conjuntos de resultados distintos?

Editar: Al hacer esto, también quería excluir la columna de Clave Primaria, que también es una identidad, y obtener restantes registros distintos. ¿Hay alguna manera de hacer esto? Tal como está, los registros distintos devuelven duplicados porque la clave principal es única para cada fila, pero todos los demás campos son los mismos.

 28
Author: Mark Struzinski, 2008-11-25

5 answers

No puede ver la publicación del foro en este momento (¿enlace roto?), así que tal vez esta no es la respuesta, pero se puede añadir un DistinctRootEntityResultTransformer:

session.CreateCriteria(typeof(Product)
    .Add(...)
    .SetResultTransformer(new DistinctEntityRootTransformer())
 23
Author: Juanma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-25 17:25:36

Para realizar una consulta distinta, puede establecer la proyección en los criterios en Proyecciones.Distinto. A continuación, se incluyen las columnas que desea devolver. El resultado se vuelve a convertir en un objeto de tipo fuerte configurando el transformador de resultados a AliasToBeanResultTransformer, pasando el tipo en el que se debe transformar el resultado. En este ejemplo estoy usando el mismo tipo que la entidad en sí, pero podría crear otra clase específicamente para esta consulta.

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>();

Esto crea SQL similar a (al menos en SQL Server):

SELECT DISTINCT FirstName, LastName from Person

Tenga en cuenta que solo las propiedades que especifique en su proyección se rellenarán en el resultado.

La ventaja de este método es que el filtrado se realiza en la base de datos en lugar de devolver todos los resultados a su aplicación y luego hacer el filtrado, que es el comportamiento de DistinctRootEntityTransformer.

 86
Author: Aidan Boyle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-30 18:54:40

Por si sirve de algo, NHibernate: Optimizar consultas con Proyecciones me ayudó básicamente con este mismo problema.

 6
Author: Jon Adams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-23 18:40:59

Estamos utilizando los medios más modernos y poderosos e impresionantemente pequeños de todos para manejar esto...sigue leyendo solo si estás preparado para lo increíble...y no tiene nada que ver con criterios...

CurrentSession()
    .QueryOver<GoodBadAndUgly>
    .Where(...)
    .TransformUsing(Transformers.DistinctRootEntity)

Por lo tanto, si usted ha venido aquí con la esperanza de una manera de hacer esto que tiene que evitar jugar con los Criterios a pesar de que usted aunque totalmente tendría que ir en esa dirección solo para añadir 'DISTINTO' en su SQL...no busque más

 -1
Author: beauXjames,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-11 23:19:35

También me encontré con el problema del número no distinto de elementos (uso un fetch="join" en mi archivo de asignación). Usé Linq para Nhibernate para resolver el problema, que se usa de la siguiente manera:

       var suppliers = (from supplier in session.Linq<Supplier>()
                        from product in supplier.Products
                        where product.Category.Name == produtCategoryName
                        select supplier).ToList().Distinct();
 -4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-06 20:08:45