如何在Doctrine中查询关联id不相等的ManyToMany关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Doctrine中查询关联id不相等的ManyToMany关系相关的知识,希望对你有一定的参考价值。

我确实看到this question和事件认为这是我需要的。它与我的要求非常相似。然而,chaning一个小东西似乎打破了整个逻辑。

所以这是我的架构:

/** @Entity **/
class Product
{    
    /**
     * @ManyToMany(targetEntity="Category", inversedBy="products")
     **/
    private $categories;

    public function __construct() {
        $this->categories = new DoctrineCommonCollectionsArrayCollection();
    }

    // ...
}

/** @Entity **/
class Category
{
    /**
     * @ManyToMany(targetEntity="Product", mappedBy="categories")
     **/
    private $products;

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

我需要查询所有不属于特定类别的产品。我的尝试是:

// ProductRepository

public function getProducts() {
        return $this->createQueryBuilder('p')
            ->innerJoin('p.categories', 'c')
            ->where('c.id != :id')
            ->setParameter('id', 1)
            ->getQuery()
            ->getResult();
    }

我不在这里发布我的数据,因为此查询的结果是所有产品。我有大约5000种产品,并且非常确定并非所有产品都属于我的类别。我试过不同的类别。它显示所有不依赖于我的查询的产品。

我也在这里留下SQL查询:

SELECT p0_.* FROM products p0_ 
INNER JOIN product_categories p2_ ON p0_.id = p2_.product_id
INNER JOIN categories c1_ ON c1_.id = p2_.category_id 
WHERE c1_.id != 1

另一个问题是它给了我产品重复。我可以使用group by p0_.id,但我不知道它是否有效。

我阅读了关于多对多关系以及如何查询它们的谷歌信息,但我发现它关于相等查询,我有不相等。

答案

要排除属于类别1的所有产品,您可以不在doctrine中使用表达式

$categoryProducts = $this->createQueryBuilder('p1')
                         ->select('p1.id')
                         ->innerJoin('p1.categories', 'c')
                         ->where('c.id = :id')
                         ->setParameter('id', 1)
                         ->getDQL();
$qb =  $this->createQueryBuilder('p');
$products = $qb->where(
                $qb->expr()->not(
                    $qb->expr()->in(
                        'p.id',
                        $categoryProducts
                    )
                )
            )
            ->getQuery()
            ->getResult();

另一种方法,但不确定,我想这应该通过使用左连接查询产生相同的结果

$this->createQueryBuilder('p')
    ->leftJoin('p.categories', 'c', 'WITH', 'c.id = :id')
    ->where('c.id IS NULL' )
    ->setParameters('id',1)
    ->getQuery()
    ->getResult();

以上是关于如何在Doctrine中查询关联id不相等的ManyToMany关系的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine DQL:如何使表达式反转

如何使用Symfony3在Doctrine2 Entity中运行查询查询

参考 ID 未随 Doctrine 关联更新

Doctrine - 从反面查询一对多、单向的连接表关联

如何在doctrine zend中没有实体的情况下继续加入查询构建器

如何使用 Doctrine 查询 NOT NULL?