Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从联接返回平面数组的原则DQL_Php_Doctrine Orm_Symfony - Fatal编程技术网

Php 从联接返回平面数组的原则DQL

Php 从联接返回平面数组的原则DQL,php,doctrine-orm,symfony,Php,Doctrine Orm,Symfony,我通过DQL中的常规左连接选择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_

我通过DQL中的常规左连接选择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返回准确的结果——它们只是没有以我期望的方式表达出来。我遵循的原则是关于快速加载连接的难以捉摸的文档:

这个问题很类似于

但我的选择顺序不同,因为我的联接表是多对多的。 非常感谢

提出了这一问题的一个变体:


我很惊讶,条令不支持通过联接表进行即时加载。

以下是我能想到的最好方法:

//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倍

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

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

要使用即时加载,您必须仅选择e1,而不是e1、e2和e3。是的,e1在任何表上都没有外键引用。我可以通过选择e1_2来获得一部分,但随后我失去了与e3的关系。