Posso usare una vista in linea con il criterio API?
-
26-09-2019 - |
Domanda
La NHibernate vista supporta gli Inline utilizzando criteri? Google non sembra prodotto risultati rilevanti. Ecco la domanda che ho bisogno di convertire preferibilmente utilizzando criteri.
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)
Ho già tutto convertito nella clausola dove. Quella parte non era un problema. Che si traduce in qualcosa di simile.
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>();
Si noti che sto usando il criterio di estensione Lambda. In alternativa, suppongo ho potuto creare un ulteriore Dto per selezionare tutte le colonne senza funzioni di aggregazione quindi utilizzare LINQ per fare il conteggio / somma / max / conteggio distinto.
Soluzione
Ho appena provato con HQL e non funziona (sarebbe lo stesso con l'API Criteria). Che cosa significa lavoro, tuttavia, è il seguente:
select
(select count(*) from Table1 t1),
(select sum(*) from Table2 t2)
from DummyTable dt
where rownum <= 1
DummyTable
non sta facendo altro che essere lì in modo da NHibernate non piange su di esso, e rownum <= 1
è lì per garantire NHibernate non cerca di restituire un elenco di oggetti. ; -)