[QUOTE]
Сергей Смирнов написал:
Краткий пример, практически не особо полезный, но для иллюстрации достаточно простой:
[CODE] 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 [/CODE]
Видно, что b_iblock_section_element цепляется к b_iblock_section , а вот b_iblock_element цепляется уже к b_iblock_section_element . И таких ссылающихся друг на друга таблиц в запросе может быть много. Только вот проблема: во всех примерах кода, найденных в интернете, в JOIN используются только ссылки на таблицы this и ref - то есть, на первоначальную таблицу запроса и на таблицу в текущем registerRuntimeField() . Как ссылаться на таблицы из других " runtime field " - я не нашёл.
Попытка написать аналог запроса на D7 ORM:
[CODE] 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" ; [/CODE]
В коде есть закомментированная строка - это первоначальная попытка сделать JOIN по наитию - не работает, пишет [QUOTE]Unknown reference value `se.IBLOCK_ELEMENT_ID`[/QUOTE]
Под закомментированной строкой - строка с работоспособным вариантом. Но он больше похож на кулхацкерский, чем на какой-либо штатный, т.к. использует скрытую логику генерации алиасов таблиц, типа iblock_section_se . Если в будущем авторы ORM решат использовать другую логику - то запрос отвалится.
Рабочий сгенерированный запрос выглядит так:
[CODE] 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 [/CODE]
На безрыбье и рак рыба - но можно ли такое написать поприличней?[/QUOTE]
Я посмотрел тот метод, треш какой-то. Но если я вас правильно понял, то вам может помочь следующее [CODE]$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' => 'this.se.IBLOCK_ELEMENT_ID'],
'join_type' => "INNER",
])
->setSelect(['e.NAME'])
->setFilter(['ID' => 954])
->setLimit(1)
->getQuery()[/CODE]