2012-11-30 38 views
1

我有兩個實體共享一個創建類表繼承的抽象類。我可以通過使用抽象類的存儲庫來查詢實體,並獲取擴展抽象類作爲結果的所有實體。加入關係關於Doctrine中的實體子類

$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 

子類包含到其他實體多對多的關係,所以如果我以這種方式進行查詢,這種關係導致額外的查詢,因爲他們沒有被加入。你如何查詢擴展抽象類並加入其列的實體?我試圖用左連接從語句中添加多個,但查詢返回的結果少於預期的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 :-(

回答

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; 

需要注意的是,你實際上可能造成更多的查詢被這樣運行的,如果你不小心很重要。

+0

急切地提取並不總是正確的解決方案,因爲ORM並不總是能夠將所有必要的連接添加到用於提取對象的SQL中。 – Ocramius

+0

是的,這是重要的一點。這不是一種適合所有解決方案的解決方案,它適用於我的情況。 – ornj

0

您可以使用fetch join和學說ORM的Paginatordocumentation描述:

$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 
+0

我不認爲我描述的情況做得很好。這兩個子類都有自己獨特的關係。 ManyToMany關係不存在於抽象類中。在我通過使用兩個FROM組件並使用LEFT JOIN獲取這些關係之前獲取這些實體之前。正如我確信你知道在Doctrine的Paginator中不能有兩個FROM組件,並且我不能加入抽象類或任何子類中不存在的列。 – ornj

+0

我編輯了我原來的帖子,給查詢生成器導致查詢次數減少但結果丟失 – ornj

+0

@ornj恐怕沒有真正的解決方案。你可以做的是將這些關係映射爲「EXTRA_LAZY」(http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#manytomany)。只有在訪問它時纔會實例化該集合。另外,考慮刪除雙向關聯(http://www.slideshare.net/guilhermeblanco/orm-dont-kill-your-db-developers-do) – Ocramius