ActiveRecord consulta (Castle, Performance)
-
06-07-2019 - |
Pergunta
Eu tenho 3 tabelas:
- Partes :
Name
: nome interno,Active
: bool - Idiomas : lista de idiomas (inglês, francês, alemão, ....)
- PartsTranslations :.
RealName
e Id da dos outros 2 mesas
Gostaria de obter uma lista de Partes me dizendo o name
interna, estado active
e quantas traduções estão faltando (total lang subtrair traduções feitas)
Eu fiz esta consulta SQL que está me dando o que eu preciso (eu não sei se esta é a melhor maneira de fazê-lo ou não, mas ele está trabalhando):
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º questão -? Como posso fazer esta consulta usando Castle ActiveRecord
2º questão -? Como está o desempenho da consulta final (um caro)
Graças
Solução
Eu era capaz de fazer esta consulta no ActiveRecord usando HqlBasedQuery
, assim que eu postar aqui a resposta para ajudar os outros na mesma situação que eu.
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]
};
Eu também tenho pagination feita neste consulta e também me dar stronged objetos PartProjection
digitados. Esta classe não precisa ter nenhum parâmetro ActiveRecord.
Outras dicas
Eu não posso ajudar com ActiveRecord, mas esta consulta deve executar melhor do que aquele com uma subconsulta correlacionada.
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, se você quiser usar a subconsulta correlacionada, você não precisa escolher entre Parts
nele novamente:
SELECT
p.name,
p.active,
(SELECT count(*) FROM Languages) -
(SELECT count(*) FROM PartsTranslations WHERE divid = p.id)
FROM Parts p;