Doctrine DQL通过join返回扁平化数组

4

我正在使用DQL通过正常的LEFT JOIN选择3个实体。它们通过联接表相关联,这些表也有实体定义以及注释关系。 查询执行没有问题,但我的结果被返回为一个平坦的数组。我希望得到一个包含三个实体作为每个索引的数组元素的数组:

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 返回准确的结果——只是它们的格式并非我所期望的。我在遵循 Doctrine(难以捉摸的)关于急切加载连接的文档:

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

我很惊讶 Doctrine 不支持通过连接表进行急切加载。


要使用贪婪加载,你必须只选择e1而不是e1、e2和e3。 - Alsatian
是的,e1在任何表上都没有外键引用。我可以通过选择“e1_2”来完成部分工作,但这样就失去了与“e3”的关联。 - eggmatters
2个回答

3

在查询中调用getScalarResult()而不是getResult(),您将获得每个记录的所有联接表字段合并为一个数组:

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

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

这很有效,因为当你只想从一个查询结果中获取结果时,你执行了3倍的查询!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接