Symfony2高效显示类别及相关产品列表

时间:2011-12-01 08:29:07

标签: php symfony doctrine-orm

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

$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 个答案:

答案 0 :(得分:1)

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

<?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使自定义查询在同一查询中获取产品,在模板中迭代时避免任何进一步的查询。