Краткий пример, практически не особо полезный, но для иллюстрации достаточно простой:
Код |
---|
SEL ECT e.NAME
FR OM b_iblock_section s
INNER JOIN b_iblock_section_element se on se.IBLOCK_SECTION_ID = s.ID
INNER JOIN b_iblock_element e on e.ID = se.IBLOCK_ELEMENT_ID
WHERE s.ID = 954
LIMIT 1 |
Видно, что
b_iblock_section_element цепляется к
b_iblock_section, а вот
b_iblock_element цепляется уже к
b_iblock_section_element. И таких ссылающихся друг на друга таблиц в запросе может быть много. Только вот проблема: во всех примерах кода, найденных в интернете, в JOIN используются только ссылки на таблицы
this и
ref - то есть, на первоначальную таблицу запроса и на таблицу в текущем
registerRuntimeField(). Как ссылаться на таблицы из других "
runtime field" - я не нашёл.
Попытка написать аналог запроса на D7 ORM:
Код |
---|
use Bitrix\Main\DB\SqlExpression;
use Bitrix\Iblock\{SectionTable, SectionElementTable, ElementTable};
$q = SectionTable::query()
->registerRuntimeField('se', [
'data_type' => SectionElementTable::class,
'reference' => ['=ref.IBLOCK_SECTION_ID' => 'this.ID'],
'join_type' => "INNER",
])
->registerRuntimeField('e', [
'data_type' => ElementTable::class,
//'reference' => ['=ref.ID' => 'se.IBLOCK_ELEMENT_ID'],
'reference' => ['=ref.ID' => new SqlEx * pression('?#','iblock_section_se.IBLOCK_ELEMENT_ID')],
'join_type' => "INNER",
])
->setSelect(['e.NAME'])
->setFilter(['ID' => 954])
->setLimit(1)
->getQuery()
;
echo "$q\n"; |
В коде есть закомментированная строка - это первоначальная попытка сделать JOIN по наитию - не работает, пишет
Цитата |
---|
Unknown reference value `se.IBLOCK_ELEMENT_ID` |
Под закомментированной строкой - строка с работоспособным вариантом. Но он больше похож на кулхацкерский, чем на какой-либо штатный, т.к. использует скрытую логику генерации алиасов таблиц, типа
iblock_section_se. Если в будущем авторы ORM решат использовать другую логику - то запрос отвалится.
Рабочий сгенерированный запрос выглядит так:
Код |
---|
SEL ECT
`iblock_section_e`.`NAME` AS `IBLOCK_SECTION_e_NAME`
FR OM `b_iblock_section` `iblock_section`
INNER JOIN `b_iblock_section_element` `iblock_section_se` ON `iblock_section_se`.`IBLOCK_SECTION_ID` = `iblock_section`.`ID`
INNER JOIN `b_iblock_element` `iblock_section_e` ON `iblock_section_e`.`ID` = `iblock_section_se`.`IBLOCK_ELEMENT_ID`
WHERE `iblock_section`.`ID` = 954
LIMIT 0, 1 |
На безрыбье и рак рыба - но можно ли такое написать поприличней?