2017-12-27 318 views
0

我有一个家谱这样的:自参照孩子不附

class Family 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var Family 
    * 
    * @ORM\ManyToOne(targetEntity="Family", inversedBy="children") 
    */ 
    private $parent; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string") 
    */ 
    private $name; 

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

    // [...] 
} 

我试图findAll(),并得到家长和孩子连接

$familyRepo = $this->em->getRepository(Family::class); 
$families = $familyRepo->findAll(); 
foreach ($families as $family) { 
    dump($family->getParent()->getName()); 
} 

我可以看到父母的名字甩并且只执行一个查询,所以他们很好地连接。

但是,如果我试图表明孩子:

dump($family->getChildren()->count()); 

我看到尽可能多的查询,有家庭。

我怎样才能让父母亲陪伴的孩子? (没有更多疑问)

我忘了什么?

回答

0

在一个一对多的关系为$children您可以指定如下,以预先抓取对象:

/** 
* @var ArrayCollection 
* 
* @ORM\OneToMany(targetEntity="Family", mappedBy="parent", fetch="EAGER") 
*/ 
private $children; 

docs看到其他PARAMS。

+0

我希望孩子们不要一直热切地提取。除此之外,我也尝试过,但某些家庭仍然加载了额外的查询。 –

+0

然后,在您的FamilyRepository中,您需要添加一个'findAllSomething'方法,您可以在其中添加连接“children”关系的查询,以便在单个查询中获取它们。当你想要使用这种查找器而不是普通的'findAll'来保存查询时。 – dlondero

+0

这是一个想法,我虽然没有。我会试一试 –

0

按照@ dlondero的建议,我强制将深度提取放入存储库。

这里是我做的事:

public function getRootNodes($eagerLevels = 5) 
{ 
    $qb = $this->createQueryBuilder('entity0') 
     ->select('partial entity0.{id, name, parent}') 
     ->where('entity0.parent IS NULL') 
    ; 
    for ($i = 0; $i < $eagerLevels; $i++) { 
     $qb 
      ->leftJoin('entity'.$i.'.children', 'entity'.($i+1)) 
      ->addSelect('partial entity'.($i+1).'.{id, name, parent}') 
     ; 
    } 

    return $qb->getQuery()->getResult(); 
} 

这部分提取正是我需要的所以没有延迟加载发生。
我也做了深度配置的级别。