Consulta ActiveRecord (Castillo, Rendimiento)
-
06-07-2019 - |
Pregunta
Tengo 3 tablas:
- Piezas :
Nombre
: nombre interno,Activo
: bool - Idiomas : lista de idiomas (inglés, francés, alemán, ...)
- PartsTranslations :
RealName
e ID de las otras 2 tablas.
Me gustaría obtener una lista de Piezas que me indiquen el nombre
interno, el activo
estado y cómo faltan muchas traducciones (total de traducciones de sustracción lang hechas)
Hice esta consulta SQL que me da lo que necesito (no sé si esta es la mejor manera de hacerlo o no, pero está funcionando):
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º pregunta- ¿Cómo puedo hacer esta consulta usando Castle ActiveRecord?
2º pregunta- ¿Cómo es el rendimiento de la consulta final (costosa)?
Gracias
Solución
Pude hacer esta consulta en ActiveRecord usando HqlBasedQuery
, así que publico aquí la respuesta para ayudar a otros en la misma situación que yo.
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]
};
También tengo paginación hecha en esta consulta y también me da un fuerte tipo de objetos PartProjection
. Esta clase NO necesita tener ningún parámetro ActiveRecord.
Otros consejos
No puedo ayudar con ActiveRecord, pero esta consulta debería funcionar mejor que la que tiene una 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
O, si desea utilizar la subconsulta correlacionada, no necesita seleccionar entre Parts
en ella nuevamente:
SELECT
p.name,
p.active,
(SELECT count(*) FROM Languages) -
(SELECT count(*) FROM PartsTranslations WHERE divid = p.id)
FROM Parts p;