2011-01-28 12 views
6

me gustaría conseguir este SQL desde NHibernate:¿Hay proyecciones de operaciones aritméticas en NHibernate?

SELECT SUM(color_pages) * SUM(total_pages) 
FROM connector_log_entry 
GROUP BY department_name 

Pero no puedo encontrar ninguna operación aritmética (*) proyecciones en cualquier lugar.

Este es el código que tengo hasta ahora:

Session.QueryOver<ConnectorLogEntry>() 
     .SelectList(list => list 
      .SelectGroup(m => m.DepartmentName) 
      .WithAlias(() => dto.Department) 
      .Select(Projections.Sum<ConnectorLogEntry>(m => m.TotalPages)) 
      //.Select(Projections.Sum<ConnectorLogEntry>(m => m.ColorPages)) 
      .WithAlias(() => dto.TotalColorPercentage)) 
     .TransformUsing(Transformers.AliasToBean<DepartmentConsumption>()); 
+1

Incluso si puede hacerlo con ICriteria, la consulta hql será mucho más legible. – Sly

Respuesta

8

Los operadores aritméticos se pueden utilizar en consultas de criterios a través de la función SQL VarArgsSQLFunction. En su caso particular, esto sería algo como:

Session.QueryOver<ConnectorLogEntry>() 
    .SelectList(list => 
     list.SelectGroup(m => m.DepartmentName) 
      .WithAlias(() => dto.Department) 
      .Select(Projections.SqlFunction(
       new VarArgsSQLFunction("(", "*", ")"), 
       NHibernateUtil.Int32, 
       Projections.Sum<ConnectorLogEntry>(m => m.TotalPages), 
       Projections.Sum<ConnectorLogEntry>(m => m.ColorPages))) 
      .WithAlias(() => dto.TotalColorPercentage)) 
    .TransformUsing(Transformers.AliasToBean<DepartmentConsumption>()); 

Esta técnica inyecta cadenas directamente en el SQL generado, por lo que tendrá que asegurarse de que la base de datos subyacente es compatible con los operadores que utiliza.

+0

No tengo una forma rápida de comprobar si esta solución es 100% buena, pero mirando la documentación de la clase VarArgsSQLFunction estoy bastante seguro de que es lo que he estado buscando más que hace un año :) Espero esta respuesta ayudará a otros en el futuro. –

2

Es trivial con LINQ o HQL, pero Criterios y QueryOver no están optimizados para que (usted tiene que utilizar una proyección SQL)

HQL es casi lo mismo que SQL:

select sum(ColorPages) * sum(TotalPages) 
from ConnectorLogEntry 
group by DepartmentName 

LINQ no es difícil tampoco:

from entry in Session.Query<ConnectorLogEntry>() 
group entry by entry.DepartmentName into g 
select g.Sum(e => e.ColorPages) * g.Sum(e => e.TotalPages) 
+0

esta consulta en mi pregunta es solo una pequeña parte. mi consulta real es mucho más difícil entonces escribí aquí, y ya lo tengo todo con QueryOver, mover todo a hql o linq sería difícil y problemático. –

+0

Lástima. Use una proyección de SQL entonces. Buena suerte manteniéndolo. –

+0

¿Qué quiere decir con "Criteria y QueryOver no están optimizados para eso"? ¿Prevé algún problema con la escritura de una proyección personalizada que podría manejar esto por mí? – csano

Cuestiones relacionadas