Requête ActiveRecord (Castle, Performance)
-
06-07-2019 - |
Question
J'ai 3 tables:
- Pièces :
Nom
: nom interne,Actif
: bool - Langues : liste des langues (anglais, français, allemand, ....)
- PartsTranslations :
RealName
et les identifiants des 2 autres tables.
Je souhaite obtenir la liste des éléments indiquant le nom
interne, actif
statut et comment. de nombreuses traductions sont manquantes (nombre total de langues soustraites)
J'ai créé cette requête SQL qui me donne ce dont j'ai besoin (je ne sais pas si c'est le meilleur moyen de le créer ou non, mais cela fonctionne):
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º question - Comment puis-je effectuer cette requête à l'aide de Castle ActiveRecord?
2º question - Quelles sont les performances de la requête finale (coûteuse)?
Merci
La solution
J'ai pu faire cette requête dans ActiveRecord en utilisant HqlBasedQuery
, aussi je poste ici la réponse pour aider les autres dans la même situation que moi.
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]
};
J'ai également paginé cette requête et cela me donne également des objets PartProjection
typés et renforcés. Cette classe n'a besoin d'aucun paramètre ActiveRecord.
Autres conseils
Je ne peux pas vous aider avec ActiveRecord, mais cette requête devrait fonctionner mieux que celle avec une sous-requête corrélée.
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
Ou, si vous souhaitez utiliser la sous-requête corrélée, vous n'avez pas besoin de sélectionner à nouveau Parties
:
SELECT
p.name,
p.active,
(SELECT count(*) FROM Languages) -
(SELECT count(*) FROM PartsTranslations WHERE divid = p.id)
FROM Parts p;