我有一个查询从表 AND 中获取来自另一个表的相关对象计数的一些信息。我在DQL中无法表达它,因此它将返回平面数组。
这个例子取得了学校,学校名称和每所学校的学生人数:
$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();
我期待它回归:
[
[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;
}
答案 0 :(得分:1)
从使用上面的DQL看,您最终会得到混合结果以及使用$qB->getQuery()->getResult()
时的Doctrine默认行为。
SELECT u, p.quantity FROM Users u...
这里,结果将再次是每个元素的数组数组 是一个由User对象和标量值组成的数组 p.quantity。
我会尝试调试生成的SQL,如果我是对的那么就是你的原因。恕我直言,这种行为无法改变,但也许我错了。
在这种情况下,解决方案可以编写一个protected
PHP函数,以便根据需要展平数组。
<强>更新强>
我还没有尝试,但似乎有可能使用Doctrine Events来实现这一目标。 preSelect
或postSelect
没有内置事件,但您可以创建自己的事件并正确注册,以便随时调用它。如前所述,我没有尝试,我不确定这是否可能使用任何事件(我可能是错的)。
只是旁注,我不会尝试过多地复杂化这一点,当你可以通过创建一个可以重用的私有公共函数在控制器上轻松地为实体添加一层复杂性时任何一点。
更多信息: