Puis-je utiliser des vues inline avec l'API de critères?
-
26-09-2019 - |
Question
Est-ce que NHibernate support vues inline en utilisant critères? Google ne semble pas renvoyer des résultats pertinents. Voici la requête que je dois convertir de préférence en utilisant critères.
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)
Je l'ai déjà tout converti dans la clause where. Cette partie avait pas de problème. Ce qui se traduit par quelque chose comme.
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>();
Notez que j'utilise l'extension de critères Lambda. Sinon, je suppose que je pourrais créer un Dto supplémentaire pour sélectionner toutes les colonnes sans fonctions d'agrégation puis utilisez LINQ pour faire le compte / somme / max / compte distinct.
La solution
Je viens d'essayer avec HQL et il ne fonctionne pas (serait la même chose avec l'API critères). Qu'est-ce que le travail, cependant, est la suivante:
select
(select count(*) from Table1 t1),
(select sum(*) from Table2 t2)
from DummyTable dt
where rownum <= 1
DummyTable
ne fait rien d'autre que d'être là pour NHibernate ne pleure pas, et rownum <= 1
est là pour assurer NHibernate ne cherche pas à retourner une liste d'objets. ; -)