2011-12-01 58 views
2

我有对象CategoryProduct关系(一对多)。我想显示与它们相关的所有类别和对象的列表。如果我使用:Symfony2高效显示类别和相关产品列表

$categories = $this->getDoctrine()->getRepository('AcmeZebraBundle:Category')->findAll(); 

而不是显示此类似:

<ul> 
{% for category in categories %} 
    <li>{{ category.name }}</li> 
    <ul> 
    {% for product in category.products %} 
    <li>{{ product.name }}</li> 
    {% endfor %} 
    </ul> 
{% endfor %} 
</ul> 

它会生成每个类别的附加查询。 我试图将产品添加到类别 - 而不是findAll()我使用了一种方法来检索所有对象并将它们添加到适当类别的ArrayCollection。但是这并不减少查询次数。

public function findAllLoadProducts() 
{ 
    $categories = $this->findAll(); 
    $categortiesById = array(); 

    foreach ($categories as $category) 
    { 
     $categortiesById[$category->getId()] = $category; 
    } 

    $products = $this->getEntityManager()->getRepository('AcmeZebraBundle:Product')->findAll(); 

    foreach ($products as $product) 
    { 
     $categortiesById[$product->getCategory()->getId()]->getProducts()->add($product); 
    } 

    return $categortiesById; 
} 

回答

1

您需要将产品水合到自定义查询中的类别。创建在同一个包来分类实体库(或使用它,如果你已经创建了它):

<?php 
/* src/Acme/ZebraBundle/Repository/CategoryRepository.php */ 
namespace Acme\ZebraBundle\Repository; 

use Doctrine\ORM\EntityRepository; 

class CategoryRepository extends EntityRepository 
{ 
    public function retrieveHydratedCategories() 
    { 
     return $this->createQueryBuilder('c') 
        ->select('c, p') 
        ->leftJoin('c.products', 'p') 
        ->getQuery() 
        ->execute(); 
    } 
} 

然后,您可以取代您以前的“的findall”的使用此查询:

$categories = $this->getDoctrine()->getRepository('AcmeZebraBundle:Category')->retrieveHydratedCategories(); 

leftJoin使自定义查询获取相同查询中的产品,避免在模板中迭代查询时进一步查询。

+0

如何在不加载每个类别的全部产品收集的情况下以这种方式获得类别产品的计数? –

相关问题