在Doctrine中加入实体子类的关系

时间:2012-11-30 21:23:58

标签: php mysql symfony doctrine dql

我有两个实体共享一个创建类表继承的抽象类。我可以通过使用抽象类'存储库来查询实体,并获取扩展抽象类的所有实体作为结果。

$qb = $this->createQueryBuilder('c')
    ->where('c.featured = true')
    ->orderBy('c.sticky', 'DESC')
    ->addOrderBy('c.weight', 'ASC')
    ->setFirstResult($offset)
    ->setMaxResults($limit);

// Returns 8 results, results in 34 queries

子类包含与其他实体的ManyToMany关系,因此如果我以这种方式查询,那些关系会导致其他查询,因为它们没有被连接。如何查询扩展抽象类并加入其列的实体?我尝试使用左连接添加多个语句,但查询返回的结果少于预期的8个结果。该查询构建器看起来像这样:

$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select(array(
    'a', 'artist', 'country', 
    't', 'artwork', 'user'))
   ->from('AcmeArtworkBundle:Artwork', 'a')
   ->from('AcmeTourBundle:Tour', 't')
   ->leftJoin('a.artist', 'artist')
   ->leftJoin('a.country', 'country')
   ->leftJoin('t.artwork', 'artwork')
   ->leftJoin('t.user', 'user')
   ->where('a.featured = true')
   ->andWhere('t.featured = true')
   ->orderBy('a.sticky', 'DESC')
   ->addOrderBy('t.sticky', 'DESC')
   ->addOrderBy('a.weight', 'ASC')
   ->addOrderBy('t.weight', 'ASC')
   ->setFirstResult($offset)
   ->setMaxResults($limit);

// 5 results :-(

2 个答案:

答案 0 :(得分:0)

您可以使用fetch join中描述的Paginator和Doctrine ORM的documentation

$qb = $em->createQueryBuilder()
    ->select('c', 'd')
    ->from('MyInheritanceClass', 'c')
    ->join('c.d', 'd')
    ->where('c.featured = true')
    ->orderBy('c.sticky', 'DESC')
    ->addOrderBy('c.weight', 'ASC')
    ->setFirstResult($offset)
    ->setMaxResults($limit);

$paginator = new \Doctrine\ORM\Tools\Pagination($qb);

var_dump(count($paginator)); // 8 results, 2 queries

答案 1 :(得分:0)

根据@Ocramius提供的链接提供的信息,默认情况下,Doctrine使用延迟加载加载实体。只有在需要时才会获取关联。您可以通过将获取模式设置为EAGER来告诉Doctrine自动获取关联。

/**
 * @var string $date
 *
 * @ORM\ManyToOne(targetEntity="Date", inversedBy="artwork", cascade={"persist"}, fetch="EAGER")
 * @ORM\JoinColumn(name="date", referencedColumnName="id")
 */
private $date;

重要的是要注意,如果你不小心,你实际上可以通过这样做来运行更多的查询。