我有一个看起来像这样的实体:
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();
我希望从这个方法返回的数组结果看起来与此类似:
root1:
child1:
subchild1a
subchild2a
child2:
subchild1b
subchild2b
subchild3b
subsubchild1b
child3:
subchild1c
root2:
....
....
有没有办法从Doctrine 2中收集结果,以便以这种方式构建数组结果?如果没有,你将如何构建这个数组?我仍在使用Doctrine 2,我注意到$privileges
数组中的每个元素都有$privilege->getChildren()
,它返回PersistentCollection
,显然不是实际记录。
如果我必须自己构建这个嵌套树(即:在Doctrine中没有内置方法来实现它),我如何将此PersistentCollection
返回到实际数据中,以便我可以构建某种递归方法为我建造它?我正在浏览文档,但显然是在错误的地方。
答案 0 :(得分:1)
结果已经在嵌套树中。可以迭代PersistentCollection
,就好像它是一个数组:
foreach($parent->getChildren() as $child) {
// $child is an instance of Privilige
}
仍然应该尝试$privileges = $q->getArrayResult();
并查看是否会提供您想要的结果。
答案 1 :(得分:1)
我认为您正在寻找的内容被称为"一对多自我引用的关联"在文档中:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-one-self-referencing
以下是文档中类别层次结构的代码:
<?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();
}
}
&#34;这有效地模拟了类别的层次结构,从数据库的角度来看,这被称为邻接列表方法。&#34;
所以我认为这应该为你完成所有工作,并创建你需要的数组层次结构。
由于您已经在文档中添加了注释,因此您的$parent->getChildren()
应该已经包含了所有层次结构,正如@rojoca所说。