Doctrine 2自引用实体,没有不必要的查询

时间:2013-05-23 13:40:35

标签: doctrine-orm zend-framework2

我正在尝试自我引用的实体在每次获取一个对象的子节点时停止查询数据库,并在一个查询中获取整个树。

这是我的实体:

/**
 * @ORM\Entity(repositoryClass="ExampleRep")
 * @ORM\Table(name="example_table")
 */
class Example {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer", nullable=false);
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Example", inversedBy="children")
     * @ORM\JoinColumn(name="parent", referencedColumnName="id", onDelete="SET NULL")
     */
    private $parent = null;

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

}

我正在使用queryBuilder调用我的日期,如:

$query = $this->createQueryBuilder('e');
$query->orderBy('e.parent', 'ASC');
$example_data = $query->getQuery()->getResult();

当我循环我的example_data并调用getChildren时,即使同一个对象已在查询中调用,也会进行另一个查询。

我按照这里的示例:Doctrine - self-referencing entity - disable fetching of children但是当我这样做时,我的getChildren什么都不返回。

有没有办法获取我的数据而不会使用多个请求重载数据库?

1 个答案:

答案 0 :(得分:4)

如果您知道树的深度,则可以执行自定义dql查询并执行:

return $this->createQueryBuilder('example')
    ->addSelect('children')
    ->leftJoin('example.children', 'children')
    ->addSelect('subChildren')
    ->leftJoin('children.children', 'subChildren')
;

否则,如上所述here,您可以生成一个平面结果集,然后从中构造树。

我使用物化路径进行了这种实现,但没有任何事情禁止您使用外键比较来执行此操作:

https://github.com/KnpLabs/DoctrineBehaviors/blob/master/src/Knp/DoctrineBehaviors/ORM/Tree/Tree.php#L119

https://github.com/KnpLabs/DoctrineBehaviors/blob/master/src/Knp/DoctrineBehaviors/Model/Tree/Node.php#L219