Я следующий объект:Doctrine 2: выбор сущностей полей, в том числе связанных полей
/**
* @ORM\Table(name="Employee")
*
@ORM\Entity(repositoryClass="Project\BackendBundle\Entity\Repository\EmployeeRepository")
*/
class Employee
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Division")
* @ORM\JoinColumn(name="division_id", referencedColumnName="id")
* @Expose
**/
private $division;
/**
* @ORM\ManyToOne(targetEntity="Position")
* @ORM\JoinColumn(name="position_id", referencedColumnName="id")
*/
private $position;
.....
}
С моим REST API, я хочу сделать фильтр под названием «поля», где я ставлю запятой список разделенных полей объектов, которые я хочу получить. Кроме того, I хотел бы разместить связанные поля. Таким образом, запрос выглядит так:
/api/employee?fields=id,division
проверить эти поля, если они существуют в полях сущностей или карте ассоциации.
Каждое связанное с ним поле добавляется в запрос, как это:
foreach ($this->assoc as $key => $mapping) {
$queryBuilder
->addSelect(substr($key, 0, 1) . ' AS ' . $key)
->leftJoin(
$mapping['targetEntity'],
substr($key, 0, 1),
\Doctrine\ORM\Query\Expr\Join::WITH,
substr($key, 0, 1) . ' = u.' . $key
);
}
Из запроса выше я получаю следующее DQL:
SELECT u.id, d AS division FROM Project\BackendBundle\Entity\Employee u LEFT JOIN Project\BackendBundle\Entity\Division d WITH d = u.division
Все нормально, я получаю ожидаемый результат (var_dump()
):
array (size=1)
0 =>
array (size=2)
'division' =>
object(Project\BackendBundle\Entity\division)[645]
private 'id' => int 20
private 'name' => string 'division1' (length=9)
'id' => int 890
Теперь, если я добавлю еще одно связанное поле в свой запрос г поля:
/api/employee?fields=id,division,position
Я получаю следующее DQL:
SELECT u.id, d AS division, p AS position FROM Project\BackendBundle\Entity\Employee u LEFT JOIN Project\BackendBundle\Entity\Division d WITH d = u.division LEFT JOIN Project\BackendBundle\Entity\Position p WITH p= u.position
Результаты теперь выглядит следующим образом:
array (size=2)
0 =>
array (size=1)
'division' =>
object(Project\BackendBundle\Entity\Kategorija)[672]
private 'id' => int 20
private 'name' => string 'division1' (length=9)
1 =>
array (size=2)
'position' =>
object(Project\BackendBundle\Entity\Position)[629]
private 'id' => int 15
private 'name' => string 'Manager' (length=7)
'id' => int 890
Проблема заключается в том, что теперь результат одного объекта лежит в двух массивы вместо одного.
Ожидаемый результат был:
array (size=1)
0 =>
array (size=3)
'division' =>
object(Project\BackendBundle\Entity\Kategorija)[672]
private 'id' => int 20
private 'name' => string 'division1' (length=9)
'position' =>
object(Project\BackendBundle\Entity\Position)[629]
private 'id' => int 15
private 'name' => string 'Manager' (length=7)
'id' => int 890
Что я пропускаю или делаю неправильно?
EDIT
Я понял, что я получаю Поля неправильного путь. Я начал использовать функции PARTIAL.
По запросу /api/employee?fields=id,division
DQL выглядит следующим образом:
SELECT partial u.{id,division} FROM Project\BackendBundle\Entity\Employee u
И результат:
array (size=1)
0 =>
array (size=3)
'division' =>
object(Project\BackendBundle\Entity\Kategorija)[672]
private 'id' => int 20
private 'name' => string 'division1' (length=9)
'position' =>
object(Project\BackendBundle\Entity\Position)[629]
private 'id' => int 15
private 'name' => string 'Manager' (length=7)
'id' => int 890
Вы можете видеть, что я получаю запрошенные объектные поля + все связанные с ним поля, независимо от того, что Я запросил только одно связанное поле.
Как получить эти связанные поля также отфильтрованы?
Или вы можете просто выбрать нужного сотрудника (без сложных запросов), получить массив запрошенных имен полей и передать его в JMS Serializer (который вы, скорее всего, используете) в качестве групп сериализации. Кроме того, ваша сущность определила бы эти группы в свойствах таким образом, чтобы позиция имела бы «позицию» группы, идентификатор имел бы группу «id» и так далее. Таким образом, сериализатор получит только те свойства из вашего объекта, которые вы передали как группы – nikita2206