Получить плоский массив при создании множественных выделений в Doctrine - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть запрос, который выбирает некоторую информацию из таблицы. И Количество связанных объектов из другой таблицы. У меня проблемы с выражением в 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), что означает, что я бы придется заново переназначить поля.

Возможно, это связано с тем, как Учение относится к сущностям. Вот школьный объект примера:

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

1 Ответ

0 голосов
/ 26 апреля 2018

Из вышеприведенного DQL кажется, что вы получаете смешанные результаты, и это поведение Doctrine по умолчанию при использовании $qB->getQuery()->getResult().

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

Здесь результатом снова будет массив массивов с каждым элементом будучи массивом, состоящим из объекта User и скалярного значения p.quantity.

Я бы попытался отладить сгенерированный SQL, и если я прав, то есть ваша причина. ИМХО такое поведение нельзя изменить но возможно я ошибаюсь.

В этом случае решением может быть написание protected PHP-функции для выравнивания массива, как вы хотите.

Обновление:

Я не пробовал, но кажется возможным использовать Doctrine Events для достижения этой цели. Для preSelect или postSelect нет встроенных событий, однако вы можете создать собственное событие и правильно зарегистрировать его, чтобы вы могли вызывать его в любой момент. Как я уже говорил, я не пытался, и я совсем не уверен, что это возможно при любом событии (я могу ошибаться).

Просто примечание: я бы не стал слишком сильно усложнять это, вы добавляете слой сложности к сущности, когда вы можете легко сделать это на своем контроллере, создав частную | публичную функцию, которую вы можете использовать повторно в любая точка.

Подробнее:

...