简体   繁体   中英

Doctrine DQL returning flat array from join

I am selecting 3 entities via regular LEFT JOIN in DQL. They are related via join tables which also have entities defined for them as well as annotated relationships. The query executes without issue but my results are returned as a flat array. I would expect an array with the three entities as array elements for each index:

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');

When I call getResult() on the query, either hydrating as an object or an array, I get a flat results set:

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 ( ... ),
)

I would expect, or like to have a multi dimensional array:

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

The results are not related by row. Nor are they in any predictable order that I can group them by with array_chunk()

The generated sql runs fine. The DQL returns accurate results -- they're just not formulated in a way that I would expect. I am following Doctrines (elusive) documentation on eager loading joins:

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

This question is very similar to

Doctrine DQL returns multiple types of entities

But my select order is different as my join tables are many-to-many. Much thanks!

A variant of this question was asked:

Getting Doctrine DQL results the SQL way

I'm pretty surprised that doctrine does not support eager loading via join table.

Here is the best that I could come up with:

//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.
}

This works great because you're performing 3XN the number of queries when you're only trying to get results from one!

Call getScalarResult() instead of getResult() on your query and you will get all fields of all joined tables merged into one array per record:

# Replace this call ...
$query->getQuery()->getResult();
# ... by that call ...
$query->getQuery()->getScalarResult();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM