【问题标题】:How to select used items in a ManyToMany Doctrine relation如何在多对多原则关系中选择使用过的项目
【发布时间】:2017-05-14 20:21:45
【问题描述】:

我有两个由双向多对多关系链接的实体(项目和标签),我想显示在与另一个实体(项目)的关系中实际使用的实体(标签)记录:

这是我的项目实体:

class Item
{
    /**
     * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Tag", inversedBy="items")
     */
    private $tags;
}

还有我的标签实体:

class Tag
{
    /**
     * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Item", mappedBy="tags")
     */
    private $items;
}

现在在我的标签存储库中我已经尝试过了:

class TagRepository extends \Doctrine\ORM\EntityRepository
{
    public function findAllUsed()
    {
        return $this->createQueryBuilder('t')
            ->leftJoin('t.items', 'items')
            ->groupBy('items.id')
            ->having('COUNT(t.id) > 0')
            ->orderBy('t.name', 'ASC')
            ->getQuery()
            ->getResult();
    }
}

但它并没有给我我期望的结果......有人可以帮忙吗?谢谢!

【问题讨论】:

    标签: symfony doctrine-orm


    【解决方案1】:

    问题

    我没有测试,但您的错误似乎在 count 子句中。您正在计算标签having('COUNT(t.id) > 0')。所以它将返回所有标签。 另一个错误是您按“项目”分组并仅选择“t”。你不需要分组。

    解决方案

    在having子句中更改“items”的“tags”。

    public function findAllUsed()
    {
        return $this->createQueryBuilder('t')
            ->leftJoin('t.items', 'items')            
            ->having('COUNT(items.id) > 0')
            ->orderBy('t.name', 'ASC')
            ->getQuery()
            ->getResult();
    }
    

    另一种可能的更简单的方法是像@KevinTheGreat 那样做一个 innerJoin,但检查不再需要有或 where 子句:

    public function findAllUsed()
    {
        return $this->createQueryBuilder('t')
            ->innerJoin('t.items', 'items')           
            ->orderBy('t.name', 'ASC')
            ->getQuery()
            ->getResult();
    }
    

    【讨论】:

    • 第二种方案简单易行!我应该多学习一点我的 SQL 语言...谢谢 Vinicius!
    【解决方案2】:

    我是从头顶上做的,但它应该可以工作,我使用了一个 innerJoin 而不是 leftJoin,然后添加了一个 where 以确保您获得链接的记录:

    public function findAllUsed()
        {
            return $this->createQueryBuilder('t')
                ->innerjoin('t.items', 'i')
                ->groupBy('i.id')
                ->where('i.id = t.items')
                ->having('COUNT(t.id) > 0')
                ->orderBy('t.name', 'ASC')
                ->getQuery()
                ->getResult();
        }
    }
    

    我用这个例子来制定答案:Query on a many-to-many relationship using Doctrine with Symfony2

    【讨论】:

    • 我有错误“'items GROUP BY':错误:无效的 PathExpression。StateFieldPathExpression 或 SingleValuedAssociationField 应为。”现在。
    • 你把-groupBy('items.id')改成('i.id')了吗
    • 你的回答有点多余。因为where('i.id = t.items') 已经包含在内连接中了。
    猜你喜欢
    • 2012-09-11
    • 2019-08-30
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多