2016-08-08 7 views
2

Я выбираю 3 объекта через регулярную LEFT JOIN в DQL. Они связаны через таблицы соединений, которые также имеют сущности, определенные для них, а также аннотированные отношения. Запрос выполняется без проблем, но мои результаты возвращаются как плоский массив. Я ожидал бы массив с тремя субъектами в качестве элементов массива для каждого индекса:Doctrine DQL, возвращающий плоский массив из соединения

SELECT e1, e2, e3 FROM AppBundle:EntityOne 
JOIN AppBundle:JoinEntityOneWithTwo e1_2 WITH e1_2.entity1 = e1.id 
JOIN AppBundle:EntityTwo e2 WITH e1_2.entity2 = e2.id 
JOIN AppBundle:JoinEntityOneWithThree e1_3 WITH e1_3.entity1 = e1.id 
JOIN AppBundle:EntityThree e3 WITH e3.id = e1_3.entity3 
WHERE e1.some_field IN ('some','values','in','e1'); 

Когда я называю getResult() по запросу, либо увлажняющим как объект или массив, я получить набор плоских результаты:

array(
/AppBundle/Entity/EntityOne (...), 
/AppBundle/Entity/EntityTwo (...), 
/AppBundle/Entity/EntityThree (...), 
/AppBundle/Entity/EntityOne (...), 
/AppBundle/Entity/EntityTwo (...), 
/AppBundle/Entity/EntityThree (...), 
/AppBundle/Entity/EntityTwo (...), 
/AppBundle/Entity/EntityThree (...), 
/AppBundle/Entity/EntityOne (...), 
) 

Я бы ожидать, или хотел бы иметь многомерный массив:

Array(
[0] => Array(
    [0] /AppBundle/Entity/EntityOne, 
    [1] /AppBundle/Entity/EntityTwo, 
    [2] /AppBundle/Entity/EntityThree 
), 
[1] => . . . 
) 

результаты не связаны построчно. Они также не могут быть в любом предсказуемом порядке, я могу сгруппировать их с помощью array_chunk()

Сгенерированный sql отлично работает. DQL возвращает точные результаты - они просто не сформулированы так, как я ожидал. Я следую доктринам (неуловимая) документация по нетерпеливой загрузке присоединяется:

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html

Этого вопрос очень похож на

Doctrine DQL returns multiple types of entities

Но мой выбор для того, отличаются, как мои присоединиться таблицы многочастичные слишком много. Большое спасибо!

Вариант этого был задан вопрос:

Getting Doctrine DQL results the SQL way

Я очень удивлен, что доктрина не поддерживает жадную загрузку через таблицу соединения.

+0

Для использования жадной загрузки вы должны выбрать e1 только и не e1, e2 и e3. – Alsatian

+0

Да, e1 не имеет ссылки на внешний ключ на любой таблице. Я мог бы получить часть пути, выбрав «e1_2», но затем я потеряю связь с «e3». – eggmatters

ответ

1

Вот лучшее, что я мог придумать:

//in my entity repository: 
public function getFoo($hydrate = true) { 
    $sql = "SELECT e1, e2, e3 FROM entity_one 
      JOIN entity_one_entity_two e1_2 ON e1_2.entity_one_id = e1.id 
      JOIN entity_two e2 ON e1_2.entity_two_id = e2.id 
      JOIN entity_one_entity_three e1_3 ON e1_3.entity_one_id = e1.id 
      JOIN entity_three e3 ON e3.id = e1_3.entity_three.id 
      WHERE e1.some_field IN ('some','values','in','e1')"; 
    $stmt = $con->prepare($sql); 
     $stmt->execute(); 
    return ($hydrate) 
    ? $this->hydrateResponses($stmt->fetchAll(PDO::FETCH_ASSOC)) 
     : $stmt->fetchAll(PDO::FETCH_ASSOC); 
} 

public function hyrdateResponses($responses) { 
    //call find by ids on repositories from array. 
} 

Это прекрасно работает, потому что вы выполняете 3XN количество запросов, когда вы только пытаетесь получить результаты от одного!

0

Вызов getScalarResult() вместо getResult() по Вашему запросу, и вы получите все поля всех соединяемых таблиц объединены в один массив на запись:

# Replace this call ... 
$query->getQuery()->getResult(); 
# ... by that call ... 
$query->getQuery()->getScalarResult(); 
Смежные вопросы