Php Doctrine2多个反向查询生成器
我有两个实体Php Doctrine2多个反向查询生成器,php,mysql,symfony,doctrine-orm,Php,Mysql,Symfony,Doctrine Orm,我有两个实体 产品和类别 Product有一个manytomy(单向)字段,该字段具有Category,其联接表名为Product\u has\u Category 我可以很容易地找到哪个类别有任何产品,但我不知道如何得到相反的结果 假设我想获取表单中某个类别的所有产品,该表单的字段是类别,因此我无法通过产品查询获取实体字段类型,否则它将失败 $form ->add('category', 'entity', array( 'class' => 'Ap
产品
和类别
Product
有一个manytomy
(单向)字段,该字段具有Category
,其联接表名为Product\u has\u Category
我可以很容易地找到哪个类别
有任何产品
,但我不知道如何得到相反的结果
假设我想获取表单中某个类别
的所有产品
,该表单的字段是类别
,因此我无法通过产品
查询获取实体字段类型,否则它将失败
$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
))
;
当然这不管用,但你知道我想做什么。由于类别
没有任何带有产品
的映射字段(因为它是单向映射),我找不到简单的那些产品
中间的表没有实体,因为我们不需要它,它只是一个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?我不知道
我已经试过了,但我只是把所有的东西都冻结了(我想大概有700多万张唱片被冻结了)
我认为这是不重复的,因为其他问题不包括
QueryBuilder
解决方案/问题,有些人可能会对如何做感到困惑。感谢@jkavalik answer引用了其他问题,让那些想知道如何在QueryBuilder中做的人
这是我使用的代码,它工作起来很有魅力
$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())
;
}
))
;
您可以使用“任意连接”@jkavalik,但我如何在QueryBuilder中做到这一点?因为这是一个原始查询。在您的代码中
p.id=:product_id
应该位于where()
,DQL中带有关键字的相当于来自SQL join的上的。否则,QB只是一个帮助您动态构建查询的工具,但它使用了所有相同的特性和语法。你可以直接用Ocramius的第二个例子重写它(或者事先用dql测试它——我想你应该只在动态查询中使用QB,其他任何东西都比dql短得多,可读性更高)。我这么做了,我的电脑被冻结了,因为我有超过700万个产品,所有东西都爆炸了。。。这是我的QB(请参见更新的问题),您两次使用c
作为别名,并且缺少将c1
与c2
连接在一起的where
条件部分。在执行这些操作时,请在运行之前使用$qb->getSQL()查看它创建的查询(它也有getDQL()方法来检查该方法)。
$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())
;
}
))
;