Php 从联接返回平面数组的原则DQL
我通过DQL中的常规左连接选择3个实体。它们通过联接表进行关联,联接表还为它们定义了实体以及注释关系。 查询执行时没有问题,但我的结果作为平面数组返回。我希望每个索引都有一个包含三个实体的数组作为数组元素: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_
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的关系。