向与Doctrine's QueryBuilder关联的子实体添加属性


Add a property to a child entity in an association with Doctrine's QueryBuilder

我正在使用Symfony 2.3和doctrine 1.2

我有以下实体结构,包括Product, Tag和TagCategory。Product与Tag有多对多关系,Tag与TagCategory有多对一关系

产品类:

class Product
{
    /**
     * @var ArrayCollection List of tags
     *
     * @ORM'ManyToMany(targetEntity="Tag", inversedBy="products")
     * @ORM'JoinTable(name="tags_productos",
     *      joinColumns={@ORM'JoinColumn(name="cod_pro", referencedColumnName="cod_pro")},
     *      inverseJoinColumns={@ORM'JoinColumn(name="cod_tag", referencedColumnName="id")}
     *      )
     */
    protected $tags;
}

TagCategory类:

class TagCategory extends BaseTagCategory
{
    /**
     * @ORM'OneToMany(targetEntity="Tag", mappedBy="category", orphanRemoval=true)
     */
    protected $tags;
}

标记类:

class Tag extends BaseTag
{
    /**
     * @Assert'NotBlank()
     * @ORM'ManyToOne(targetEntity="TagCategory", inversedBy="tags")
     * @ORM'JoinColumn(name="category_id", referencedColumnName="id", nullable=false)
     */
    protected $category;
    /**
     * @var ArrayCollection List of products that have this tag assigned
     *
     * @ORM'ManyToMany(targetEntity="Product", mappedBy="tags")
     */
    protected $products;
}

我需要做的是,对于给定的产品列表,获取这些产品所具有的标签,并且对于每个标签,获取具有该标签的产品的数量。

我还想检索按TagCategory分组的标签,因为它们需要分组呈现。

这是我尝试的查询之一,它在TagCategory Repository:

$qb->select('c as tagCategory, t as tag, COUNT(t) as total')
        ->from($this->_entityName, 'c')
        ->leftJoin('c.tags', 't')
        ->leftJoin('t.products', 'p')
        ->where(
            $qb->expr()->in('p.id', $productsIds)
            )
        ->groupBy('t.id')
    ;
这给了我一个结构如下的数组:
array(3) {
    [0]=> array(2) {
        ["tagCategory"]=> array(4) {
            ["id"]=>
            ["name"]=>
            ["slug"]=>
            ["tags"]=> array(2) {
                [0]=> array(4) {
                    ["id"]=>
                    ["order"]=>
                    ["name"]=>
                    ["slug"]=>
                }
                [1]=> array(4) {
                    ["id"]=>
                    ["order"]=>
                    ["name"]=>
                    ["slug"]=>
                }
            }
        }
        ["total"]=>
}

这个查询将一个类别中的所有标签分组,这是我想要的,但它将总数放在顶层,并作为类别中最后一个标签的总数。我需要total作为标签实体的另一个属性。

我也试过做这个查询,在标签存储库:

$qb->select('c as tagCategory, t as tag, COUNT(t) as total')
        ->from($this->_entityName, 't')
        ->leftJoin('t.category', 'c')
        ->leftJoin('t.products', 'p')
        ->where(
            $qb->expr()->in('p.id', $productsIds)
            )
        ->groupBy('t.id')
    ;

这个查询为我提供了一个标记数组,类别和总数作为属性,这是正确的,但我需要将标记分组在一个类别中:

array(4) {
    [0]=> array(2) {
        ["tag"]=> array(5) {
            ["id"]=>
            ["order"]=>
            ["name"]=>
            ["slug"]=>
            ["category"]=> array(3) {
                ["id"]=>
                ["name"]=>
                ["slug"]=>
            }
        }
        ["total"]=>
}

我需要这样的东西,能完成吗?

array(3) {
    [0]=> array(2) {
        ["tagCategory"]=> array(4) {
            ["id"]=>
            ["name"]=>
            ["slug"]=>
            ["tags"]=> array(2) {
                [0]=> array(4) {
                    ["id"]=>
                    ["order"]=>
                    ["name"]=>
                    ["slug"]=>
                    **["total"]=>**
                }
                [1]=> array(4) {
                    ["id"]=>
                    ["order"]=>
                    ["name"]=>
                    ["slug"]=>
                    **["total"]=>**
                }
            }
        }
}

谢谢。

您想要做的事情,无法通过SQL级别的单个查询完成。

您可以使用2查询或1查询与子查询。教义可能会在背景中起作用,但我不认为教义。我能做到。我怀疑教条。*将能够。

无论如何,如果您不需要tagCategory中的所有数据,那么最好的解决方案是修改第二个查询,并选择您需要的其他字段。

$qb->select('c as tagCategory, t as tag, COUNT(t) as total, c.name as tagCategory_name')
    ->from($this->_entityName, 't')
    ->leftJoin('t.category', 'c')
    ->leftJoin('t.products', 'p')
    ->where(
        $qb->expr()->in('p.id', $productsIds)
        )
    ->groupBy('t.id')
;

如果您需要,所有数据和您所描述的确切结构,选择所有tagCategories与一个查询,然后在foreach循环中配对,通过id。

下面的代码有一些错误

<我> JoinColumn = {@ORM ' JoinColumn (name = " cod_pro referencedColumnName ="cod_pro")},

应为

<我> JoinColumn = {@ORM ' JoinColumn (name = " cod_pro " referencedColumnName = " id ")},