Доктрина 2: Построение дерева вложенных массивов из само-ссылающейся сущности - PullRequest
3 голосов
/ 14 июня 2011

У меня есть сущность, которая выглядит следующим образом:

class Privilege
{
/**
 * @Id @Column(type="bigint")
 * @GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @Column(type="string",length=255)
 */
private $name;

/**
 * @Column(type="string",length=255)
 */
private $slug;

/**
 * @OneToMany(targetEntity="Privilege", mappedBy="parent")
 */
private $children;

/**
 * @ManyToOne(targetEntity="Privilege", inversedBy="children")
 * @JoinColumn(name="p_id", referencedColumnName="id")
 */
private $parent;

Если у Privilege Entity нет родителя, поле имеет значение NULL.У меня есть простой запрос, подобный этому:

    $qb = $this->em->createQueryBuilder()
        ->select('p')
        ->from('\Dashboard\Entity\Privilege', 'p')
        ->andWhere('p.parent IS NULL');

    $q = $qb->getQuery();
    $privileges = $q->getResult();

Я хотел бы, чтобы результат массива, который я возвращаю из этого метода, выглядел примерно так:результаты из Doctrine 2, поэтому он строит массив результатов таким образом?Если нет, как бы вы построили этот массив?Я все еще играю с Doctrine 2, и я заметил, что каждый элемент в моем массиве $privileges имеет $privilege->getChildren(), который возвращает PersistentCollection, очевидно, не фактическую запись.

Если мне нужно построить это вложенное дерево самостоятельно (то есть: нет встроенного в Doctrine для этого способа), как мне превратить это PersistentCollection, возвращенное в фактические данные, чтобы я мог построить какой-то рекурсивныйспособ построить это для меня?Я просматриваю документы, но явно не в том месте.

Ответы [ 2 ]

1 голос
/ 08 ноября 2014

Я думаю, что то, что вы ищете, называется «ассоциация сам-ссылающихся один-ко-многим» в документации: http://docs.doctrine -project.org / projects / doctrine-orm / en / latest / reference / ассоциативно-mapping.html # один-к-одному-автореферентно

Вот код для иерархии категорий из документов:

<?php
/** @Entity **/
class Category
{
    // ...
    /**
     * @OneToMany(targetEntity="Category", mappedBy="parent")
     **/
    private $children;

    /**
     * @ManyToOne(targetEntity="Category", inversedBy="children")
     * @JoinColumn(name="parent_id", referencedColumnName="id")
     **/
    private $parent;
    // ...

    public function __construct() {
        $this->children = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

«Это эффективно моделирует иерархию категорий и с точки зрения базы данных называется подходом со списком смежности».

Так что я думаю, что это должно сделать всю работу за вас и создать иерархию массивов, которые вам нужны.

Поскольку у вас уже есть аннотации, как в документах, ваш $parent->getChildren() должен уже содержать всю иерархию, как сказал @rojoca.

1 голос
/ 18 июня 2011

Результаты уже находятся во вложенном дереве. PersistentCollection может быть повторен, как если бы это был массив:

foreach($parent->getChildren() as $child) {
    // $child is an instance of Privilige
}

Тем не менее, вы должны попробовать $privileges = $q->getArrayResult(); и посмотреть, даст ли это результат, который вы бы предпочли.

...