我有对象Category
和Product
关系(一对多)。我想显示与它们相关的所有类别和对象的列表。如果我使用:
$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;
}
答案 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使自定义查询在同一查询中获取产品,在模板中迭代时避免任何进一步的查询。