从Doctrine2和Symfony2中的Collection获取独特属性?

时间:2013-01-25 21:12:05

标签: php mysql symfony doctrine doctrine-orm

我使用Doctrine2在Symfony2中的实体之间有多对多关联:(产品和类别)。

我想列出每个类别,然后列出该类别中的每个唯一产品名称。每个产品显然可以分为多个类别(某些类别为空)。

以下是我必须使用基本实体管理器方法等的方法。注释是PHPStorm的提示,以便代码自动完成工作。:

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

    $response = '';

    /** @var $category Category  */
    foreach ($categories as $category){

        $products = $category->getProducts();

        if (!$products->isEmpty()){

            $productArr = array();

            /** @var $product Product */
            foreach ($products as $product){
                $productArr[] = $product->getName();
            }
            $productArr = array_unique($productArr);

            $response .= $category->getName() . "\n";

            foreach ($productArr as $prod){
                $response .= "\t$prod\n";
            }
        }
    }

这可以在DB上进行30次点击。 (29类)这样很好。我的问题是想要从\ Doctrine \ Common \ Collections \ Collection

中获取唯一的产品名称

您可以看到我的复杂代码循环遍历产品名称,将它们放在一个数组中,然后在其上调用array_unique。当然有效,但必须有更优雅的方式。

1 个答案:

答案 0 :(得分:2)

您可以在存储库中创建特殊查询并使用Group By语句。这将使您的代码在EntityManager中变亮。在您的仓库中的代码下方:

修改

namespace Acme\PersonalBundle\Repository;

use Doctrine\ORM\EntityRepository;

class CategoryRepository extends EntityRepository
{
    /**
     * Fetch unique product names
     *
     */
    public function fetchUniqueProductNames()
    {
        $query = $this->getEntityManager()
            ->createQuery('
        SELECT c.name, p.name FROM AcmePersonalBundle:Category c
        JOIN c.products p
            GROUP BY p.name'
        )
        try
        {
            return $query->getResult();
        }
        catch (\Doctrine\ORM\NoResultException $e)
        {
            return null;
        }
    }

DICTINCT也可以为您提供帮助,但GROUP BY功能更强大:

        $query = $this->getEntityManager()
            ->createQuery('
        SELECT DISTINCT p.name FROM AcmePersonalBundle:Category c
        JOIN c.products p'
        //....

W3不是一个很棒的博士,但至少你明白这个想法: