理论2许多许多逆查询生成器


Doctrine2 manyToMany Inverse QueryBuilder

我有两个实体

ProductCategory

Product有一个manyToMany(单向)域,Category有一个名为product_has_category的可连接域

我可以很容易地找到哪个Category有任何Product,但我不知道如何得到逆…

假设我想在一个表单中获得所有Product的特定Category,该表单的字段是category,因此我无法获得Product查询的实体字段类型,否则它将失败。

$form
    ->add('category', 'entity', array(
        'class'     => 'AppBundle'Entity'Category',
        'property'  => 'name',
        'query_builder' => function(EntityRepository $em) use ($product) {
            return $em
                ->createQueryBuilder('c')
                ->innerJoin('AppBundle'Entity'Product', 'p', 'WITH', 'p.id = :product_id')
                ->setParameter('product_id', $product->getId())
                ;
        },
        'multiple'  => true
    ))
;

当然这行不通,但是你知道我想要做什么。由于Category没有任何与Product映射的字段(因为它是单向映射),我找不到容易的那些产品…

中间的表没有实体,因为我们不需要它,它只是一个mysql表。

运行一个MySQL查询会很容易,但我们需要它在QueryBuilder中,因为我们将在表单中使用它。

SELECT c.name 
FROM category c
INNER JOIN product_has_category pc ON pc.category_id = e.id
INNER JOIN product p ON pc.product_id = p.id
WHERE p.id = 10
;

这个,当然返回给我我想要的,因为在MySQL上我可以访问中间表,所以我可以连接所有…但是,QueryBuilder吗?我不知道

我已经尝试过了,但是我只是把所有东西都冻结了(我猜超过7M记录)

$em
->createQueryBuilder('c')
->select('c')
->innerJoin('AppBundle'Entity'Product', 'p', 'WITH', '1 = 1')
->innerJoin('p.categories', 'c')
->where('p.id = :product_id')
->setParameter('product_id', $product->getId())
;

我认为这不是重复的,因为其他问题不包括QueryBuilder解决方案/问题,有些人可能会对如何做到这一点感到困惑。

对于那些想知道如何在QueryBuilder中做到这一点的人,感谢@jkavalik参考其他问题的答案

原则2 DQL -如何选择单向多对多查询的逆侧?

这是我使用的代码,它工作起来很有魅力。

$form
    ->add('categories', 'entity', array(
        'class'     => 'AppBundle'Entity'Category',
        'property'  => 'name',
        'query_builder' => function(EntityRepository $em) use ($product) {
            return $em
                ->createQueryBuilder('c1')
                ->innerJoin('AppBundle'Entity'Product', 'p', 'WITH', '1 = 1')
                ->innerJoin('p.equipments', 'c2')
                ->where('p.id = :product_id')
                ->andWhere('c1.id = c2.id')
                ->setParameter('product_id', $product->getId())
            ;
        }
    ))
;