每个类别的学说关系检索和水合物 children

Doctrine relationship retrieve and hydrate children of every Category

根据 Doctrine 2 docs here,您可以使用具有 self-reference one-to-many 关系的 class 创建实体层次结构。我希望能够查询所有类别及其所有相关 children。

此刻,当我从控制器转储查询 returns 'uninitialized': #collection: ArrayCollection -elements: []。

我不知道如何调整 QueryBuilder 来补充 children。

CategoryRepository 中的代码:

public function retrieveHydratedCategories()
{
    return $this->createQueryBuilder('c')
                ->select('c, p, b')
                ->leftJoin('c.products', 'p')
                ->leftJoin('p.brand', 'b')
                ->Where("c.isActive = 1")
                ->getQuery()
                ->execute();
}

我的类别实体:

<?php
// src/Entity/Category.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;


/**
 * @ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
 * @ORM\Table(name="categories")
 */
class Category
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=25)
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=64)
     */
    private $brand;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $image;

    /**
     * One ProductCategory has Many ProductCategories.
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
     */
    private $children;

    /**
     * Many ProductCategories have One ProductCategory.
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    private $parent;

    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive;

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

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

    /**
     * @return Collection|Product[]
     */
    public function getProducts()
    {
        return $this->products;
    }
    public function getChildren()
    {
        return $this->children;
    }
    public function getParent()
    {
        return $this->parent;
    }
    public function getName()
    {
        return $this->name;
    }

    public function getId()
    {
        return $this->id;
    }

    public function getImage()
    {
        return $this->image;
    }

     public function setName($name)
    {
        $this->name = $name;
    }
   public function addChildren (Category $children)
   {
       $this->children[] = $children;

       return $this;
   }
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;
    }

    public function getBrand()
    {
        return $this->brand;
    }
}

Self-referencing One-To-Many 协会在收集水合作用方面与常规 One-To-Many 协会没有什么不同。如果您希望检索类别的直接 children,则必须向当前查询添加另一个联接。类似于:

public function retrieveHydratedCategories()
{
    $qb = $this->createQueryBuilder('c');
    // your other joins and conditions ...
    $qb->leftJoin('c.children', 'children')->addSelect('children');

    return $qb->getQuery()->getResult();
}

话虽这么说,但只有当你有一层深度时,这才有效。如果你想检索 children 的 children,你要么必须添加另一个连接 (see this post) or generate your tree of categories from a flat result set as discussed here.

child人的products协会也是如此。除非您在针对 children 的产品的查询中添加特定的连接,否则相应的集合不会被水化(如果 child 也是 parent 检索到的,它可能会被水化在主要结果集中...)。