2010-09-28 3 views
1

Поддерживает ли NHibernate встроенные представления с использованием критериев? Google, похоже, не возвращает никаких релевантных результатов. Вот запрос, который мне нужно преобразовать, предпочтительно используя критерии.Могу ли я использовать встроенные представления с API критериев?

SELECT COUNT (incident_count) AS incident_count, 
     SUM (total_customers) AS total_customers, 
     MAX (longest_etr) AS longest_etr, 
     COUNT (DISTINCT crew_count) AS crew_count 
    FROM (SELECT l.incident_id AS incident_count, 
       i.downstream_cust_qty_total AS total_customers, 
       TO_CHAR (MAX (l.etr_datetime), 
          'MM/DD/YYYY HH24:mi:ss' 
         ) AS longest_etr, 
       ca.crew_no AS crew_count 
      FROM district d, 
       LOCATION l, 
       ZONE z, 
       incident_device ID, 
       incident i, 
       crew_action ca 
      WHERE l.dist_no = d.dist_no 
      AND d.zone_id NOT IN (1008, 1010) 
      AND ID.location_id = l.location_id 
      AND ID.incident_id = i.incident_id 
      AND l.location_id = i.location_id 
      AND ca.incident_id = i.incident_id 
      AND ca.location_id = l.location_id 
      AND ID.call_type_cd IN ('ELEC', 'PLAN') 
      AND ID.clue_cd NOT IN (248, 258, 975) 
      AND l.fac_job_status_cd IN ('A', 'D', 'F', 'G', 'P', 'U', 'W') 
      AND z.zone_id = d.zone_id 
      AND ca.crew_action_id = l.crew_action_id 
      AND l.dist_no = 24 
      AND l.primary_loc_flg = 'T' 
     GROUP BY l.incident_id, i.downstream_cust_qty_total, ca.crew_no) 

У меня уже есть все, что было преобразовано в предложение where. Эта часть не была проблемой. Это переводится во что-то подобное.

GetSession().CreateCriteria(typeof (Incident),() => incidentAlias) 
    // Projection 
    .SetProjection(
     Projections.ProjectionList() 
      .Add(LambdaProjection.Count<Incident>(i => incidentAlias.IncidentId).As(() => IncidentCount)) 
      .Add(LambdaProjection.Sum<Incident>(i => incidentAlias.DownstreamCustQtyTotal).As(() => TotalCustomers)) 
      .Add(LambdaProjection.Max<Location>(l => locationAlias.EtrDatetime).As(() => LongestEtr)) 
      .Add(LambdaProjection.CountDistinct<CrewAction>(ca => crewActionAlias.CrewNo).As(() => CrewCount)) 
      .Add(LambdaProjection.GroupProperty(() => incidentAlias.IncidentId)) 
      .Add(LambdaProjection.GroupProperty(() => incidentAlias.DownstreamCustQtyTotal)) 
      .Add(LambdaProjection.GroupProperty(() => crewActionAlias.CrewNo)) 
    ) 
    // Aliases 
    .CreateAlias(() => incidentAlias.Locations,() => locationAlias) 
    .CreateAlias(() => incidentAlias.IncidentDevices,() => incidentDeviceAlias) 
    .CreateAlias(() => incidentAlias.District,() => districtAlias) 
    .CreateAlias(() => districtAlias.Zone,() => zoneAlias) 
    .CreateAlias(() => locationAlias.CrewAction,() => crewActionAlias) 
    // Criterias 
    .Add(() => locationAlias.PrimaryLocFlg == "T") 
    .Add(() => locationAlias.DistNo == districtNumber) 
    .Add(() => zoneAlias.ZoneId != 1008) 
    .Add(() => zoneAlias.ZoneId != 1010) 
    .Add(SqlExpression.In(() => locationAlias.FacJobStatusCd, new[] { "A", "D", "F", "G", "P", "U", "W" })) 
    .Add(SqlExpression.In(() => incidentDeviceAlias.CallTypeCd, new [] { "ELEC", "PLAN" })) 
    .Add(() => incidentDeviceAlias.ClueCd != "248") 
    .Add(() => incidentDeviceAlias.ClueCd != "258") 
    .Add(() => incidentDeviceAlias.ClueCd != "975") 
    .SetResultTransformer(Transformers.AliasToBean<Dto>()) 
    .List<Dto>(); 

Обратите внимание, что я использую расширение критериев лямбда. В качестве альтернативы, я полагаю, что я мог бы создать дополнительное Dto для выбора всех столбцов без агрегатных функций, а затем использовать Linq для вычисления счетчика/суммы/max/count.

+0

Этот запрос мало смысла. Это эквивалентно внутреннему запросу. Какой запрос вы действительно пытаетесь запустить? –

+0

@ Diego - очень популярный метод для Oracle -> http://www.orafaq.com/wiki/Inline_view – rebelliard

+0

@ Rafael, в примерах есть дополнительные фильтры. Это имеет смысл в этих случаях. В любом случае, «inline view» - это термин Oracle, а не NH one (и в наши дни они называются подзапросами почти всеми) –

ответ

1

Я просто попробовал его с помощью HQL, и он не работает (будет аналогичным с API критериев). Что делает работу, однако, заключается в следующем:

select 
    (select count(*) from Table1 t1), 
    (select sum(*) from Table2 t2) 
from DummyTable dt 
where rownum <= 1 

DummyTable ничего, кроме того там так NHibernate не плачь о нем не делать, и rownum <= 1 там, чтобы обеспечить NHibernate не пытается вернуть список объектов. ;-)

Смежные вопросы