Query ActiveRecord (Castle, Performance)
-
06-07-2019 - |
Domanda
Ho 3 tabelle:
- Parti :
Nome
: nome interno,Active
: bool - Lingue : elenco di lingue (inglese, francese, tedesco, ....)
- PartsTranslations :
RealName
e ID delle altre 2 tabelle.
Vorrei ottenere un elenco di Parti che mi indica il nome
, attivo
stato e come mancano molte traduzioni (totale sottrazione delle traduzioni effettuate)
Ho creato questa query SQL che mi sta dando ciò di cui ho bisogno (non so se questo è il modo migliore per farlo o no, ma funziona):
SELECT
parts1.name,
parts1.active,
(
(SELECT count(lang.id)
FROM languages AS lang)
-
(SELECT count(trans.id)
FROM parts AS parts2
INNER JOIN partstranslations as trans
ON parts2.id = trans.partid
WHERE parts2.id = parts1.id)
)
from parts as parts1;
1 & # 186; domanda- Come posso effettuare questa query utilizzando Castle ActiveRecord?
2 & # 186; domanda- Qual è il rendimento della query finale (costosa)?
Grazie
Soluzione
Sono stato in grado di effettuare questa query in ActiveRecord utilizzando HqlBasedQuery
, quindi inserisco qui la risposta per aiutare gli altri nella stessa situazione in cui mi trovo.
HqlBasedQuery query = new HqlBasedQuery(typeof(Part),
@"
SELECT
par.Id,
par.Name,
par.Active,
(SELECT count(*) - count(trans) FROM Language)
FROM Part par
LEFT JOIN par.PartsTranslations trans
GROUP BY par.Id, par.Name, par.Active, trans.Part
");
query.SetQueryRange(startId, currentPageSize);
var results = from object[] summary in
(ArrayList)ActiveRecordMediator.ExecuteQuery(query)
select new PartProjection
{
Id = (int)summary[0],
Name = (string)summary[1],
Active = (bool)summary[2],
TransMissing = (long)summary[3]
};
Ho anche impaginato questa query e mi dà anche un oggetto PartProjection
tipizzato in modo forte. Questa classe NON deve avere alcun parametro ActiveRecord.
Altri suggerimenti
Non posso fare a meno di ActiveRecord, ma questa query dovrebbe funzionare meglio di quella con una subquery correlata.
SELECT
p.name,
p.active,
(SELECT count(*) FROM languages) - count(pt.divid)
FROM
Parts p
LEFT JOIN PartsTranslations pt ON p.id=pt.divid
GROUP BY p.id, p.name, p.active
In alternativa, se si desidera utilizzare la subquery correlata, non è necessario selezionare nuovamente da Parti
:
SELECT
p.name,
p.active,
(SELECT count(*) FROM Languages) -
(SELECT count(*) FROM PartsTranslations WHERE divid = p.id)
FROM Parts p;