2011-01-28 13 views
6

Chciałbym dostać tę SQL z NHibernate:Czy są jakieś arytmetyczne projekcje operacji w NHibernate?

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

Ale nie mogę znaleźć żadnej operacji arytmetycznej (*) projekcje w dowolnym miejscu.

Jest to kod, który mam do tej pory:

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

Nawet jeśli będziesz w stanie to zrobić z ICriteria, zapytanie hql będzie znacznie bardziej czytelne. – Sly

Odpowiedz

8

Operatory arytmetyczne mogą być używane w zadawaniu zapytań za pomocą funkcji SQL VarArgsSQLFunction. W danym przypadku będzie to wyglądać mniej więcej tak:

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

Ta technika wstrzykuje się bezpośrednio do ciągów generowanych SQL, więc trzeba się upewnić, podstawowa baza danych obsługuje operatorów używać.

+0

Nie mam szybkiego sposobu sprawdzenia, czy to rozwiązanie jest w 100% dobre, ale patrząc na dokumentację klasy VarArgsSQLFunction jestem pewien, że tego właśnie szukałem więcej niż rok temu :) Mam nadzieję, że ta odpowiedź pomoże innym w przyszłości. –

2

To błahe z LINQ lub HQL, ale Kryteria i QueryOver nie są zoptymalizowane do tego (trzeba użyć Projekcja SQL)

HQL jest prawie taka sama jak SQL:

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

LINQ nie jest trudne albo:

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

to pytanie w moim pytaniu jest tylko małą częścią. moje prawdziwe zapytanie jest o wiele trudniejsze niż pisałem tutaj, i mam już wszystko z QueryOver już, przejście do hql lub linq byłoby trudne i problematyczne. –

+0

Szkoda. Użyj wtedy projekcji SQL. Powodzenia w utrzymaniu tego. –

+0

Co rozumiesz przez "Kryteria i QueryOver nie są zoptymalizowane do tego"? Czy przewidujecie jakieś problemy z pisaniem niestandardowej projekcji, która poradziłaby sobie z tym? – csano

Powiązane problemy