在 Doctrine 中进行多项选择时获取平面数组

Get flat array when making mutliple selects in Doctrine

我有一个查询,它从 table 从另一个 table 获取相关 objects 的计数。我无法用 DQL 表达它,所以它将 return 一个 平面数组 .

本例取学校、学校名称及各学校学生人数:

$qB = $this->createQueryBuilder('school')
$qB->leftJoin('school.students', 'students');
$qB->select([
    'partial school.{id, name}',
    'count(students) AS number_students',
]);
$qB->groupBy('school');
$qB->getQuery()->getResult();

我期待 return:

[
    [id => 1, 'name' => 'School A', 'number_students' => 5],
    [id => 2, 'name' => 'School B', 'number_students' => 3],
]

但我最终得到了这个:

[
    [0 => [id => 1, 'name' => 'School A'], 'number_students' => 5],
    [0 => [id => 2, 'name' => 'School B'], 'number_students' => 3],
]

作为一种解决方法,可以使用 $qB->getQuery()->getScalarResult(),但随后会转换变量名称(例如,实体变量名称 schoolName 然后会转换为数据库中的列标题 school_name),这意味着我将不得不再次重新映射字段。

这可能与 Doctrine 对待实体的方式有关。这是示例的学校实体:

class School {
    protected $id;
    protected $name;
    protected $students;
}

从上面的 DQL 看来,您最终会得到混合结果,这是使用 $qB->getQuery()->getResult() 时 Doctrine 的默认行为。

SELECT u, p.quantity FROM Users u...

Here, the result will again be an array of arrays, with each element being an array made up of a User object and the scalar value p.quantity.

我会尝试调试生成的 SQL,如果我是对的,那么这就是你的原因。恕我直言,这种行为无法改变,但也许我错了。

在这种情况下,解决方案可以是编写一个 protected PHP 函数来根据需要展平数组。

更新:

我没试过,但似乎可以使用Doctrine Events来实现这一点。 preSelectpostSelect 没有内置事件,但您可以创建自己的事件并正确注册,以便随时调用。如前所述,我没有尝试过,而且我完全不确定这是否可以使用任何事件(我可能是错的)。

附带说明一下,我不会试图将其过于复杂化,当您可以通过创建私有对象在控制器上轻松执行此操作时,您正在为实体添加一层复杂性|public您可以随时重复使用的功能。

更多信息: