在关系中使用

时间:2014-12-29 12:58:20

标签: php symfony doctrine-orm

来自官方网站:

// src/AppBundle/Entity/Category.php

// ...
use Doctrine\Common\Collections\ArrayCollection;

    class Category
    {
        // ...

        /**
         * @ORM\OneToMany(targetEntity="Product", mappedBy="category")
         */
        protected $products;

        public function __construct()
        {
            $this->products = new ArrayCollection();
        }
    }

// src/AppBundle/Entity/Product.php

// ...
class Product
{
    // ...

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     */
    protected $category;
}

数据库:

Category:
id | name
1  | main
2  | test
3  | it

Product:
id | category_id | name | created_at
1  | 1           | aaa  | 2014-10-10
2  | 1           | bbb  | 2014-11-10
3  | 2           | vvv  | 2014-09-14
4  | 1           | ddd  | 2014-12-12
5  | 3           | ccc  | 2014-11-11
6  | 2           | fsd  | 2014-11-14
7  | 3           | fff  | 2014-09-23

现在我希望获得所有产品created_at> 2014-10-01,所以:

$repository = $this->getDoctrine()
            ->getRepository('AppBundle:Category');

$query = $repository->createQueryBuilder('c');

        $query->leftJoin('c.products', 'p')
        ->andWhere('p.created_at > :date')
        ->setParameter('date', '2014-10-01');

$categories = $query->getQuery()->getResult();

并在Twig中展示:

{% for category in categories %}
  <h1>{{ category.name }}</h1>
  {% for product in category.products %}
     <h2>{{ product.name }}</h2>
  {% endfor %} 
{% endfor %}

这不会返回任何错误,但是不起作用的子句。这显示了我的所有产品,但我想只获得日期&gt;的产品2014-10-01。

2 个答案:

答案 0 :(得分:1)

当您构建查询时,搜索类别时,它会使用所有聚合对象过滤类别对象。 where子句用于过滤类别,而不是此处的产品。 如果您想过滤产品,则应使用ProductRepository创建“查询”构建器。

一些代码:

$repository = $this->getDoctrine()
        ->getRepository('AppBundle:Product');

$query = $repository->createQueryBuilder('p');
    ->select('p, c')
    ->leftJoin('p.category', 'c')
    ->andWhere('p.created_at > :date')
    ->setParameter('date', '2014-10-01');

$products = $query->getQuery()->getResult();
$res = array_reduce($products, function($r, $product) {
    $cid = $product->getCategory()->getId();
    isset($r[$cid]) || $r[$cid] = ['category'=> $product->getCategory(), 'products' => []];
    $r[$cid]['products'][] = $product;

    return $r;
}, []);

然后在树枝上

{% for r in res %}
  <h1>{{ r.category.name }}</h1>
  {% for product in r.products %}
    <h2>{{ product.name }}</h2>
  {% endfor %} 
{% endfor %}

答案 1 :(得分:1)

如果要获取产品,请在Productrepository中进行,而不是在Category中。

$entityManager = $this->getDoctrine()->getManager();

$queryBuilder = $entityManager->createQueryBuilder();

$query = $queryBuilder
    ->select(array('p'))
    ->from('AppBundle:Product', 'p')
    ->leftJoin('p.category', 'c')
    ->where($queryBuilder->expr()->gt('p.created_at', ':date'))
    ->setParameter('date', '2014-10-01')
;

$products = query->getQuery()->getResult();

将它传递给Twig。