Запрос ActiveRecord (Замок, Производительность)
-
06-07-2019 - |
Вопрос
У меня есть 3 таблицы:
- Части:
Name
:внутреннее имя,Active
:логическое значение - Языки:список языков (английский, французский, немецкий, ....)
- ЧастиПереводы:
RealName
и идентификаторы двух других таблиц.
Я хотел бы получить список Части рассказывая мне внутреннюю name
, active
положение дел и сколько переводов отсутствует (от общего количества языков вычесть сделанные переводы)
Я сделал этот SQL-запрос, который дает мне то, что мне нужно (я не знаю, лучший ли это способ сделать это или нет, но он работает):
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-й вопрос- Как я могу выполнить этот запрос с помощью Castle ActiveRecord?
2-й вопрос- Какова производительность финального запроса (дорогого)?
Спасибо
Решение
Мне удалось сделать этот запрос в ActiveRecord, используя HqlBasedQuery
, поэтому я публикую здесь ответ, чтобы помочь другим, оказавшимся в такой же ситуации, как и я.
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]
};
У меня также есть нумерация страниц для этого запроса, и это также дает мне строгий типизированный запрос. PartProjection
объекты.Этот класс НЕ нуждается в каком-либо параметре ActiveRecord.
Другие советы
Я не могу помочь с ActiveRecord, но этот запрос должен работать лучше, чем запрос с коррелированным подзапросом.
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
Или, если вы хотите использовать коррелированный подзапрос, вам не нужно выбирать из Parts
в нем еще раз:
SELECT
p.name,
p.active,
(SELECT count(*) FROM Languages) -
(SELECT count(*) FROM PartsTranslations WHERE divid = p.id)
FROM Parts p;