Doctrine orm 集合子实体上的doctrine2 dql成员

Doctrine orm 集合子实体上的doctrine2 dql成员,doctrine-orm,dql,Doctrine Orm,Dql,使用dql,我试图检查一个实体是否是集合子实体的成员 实体: 一个客户有多个订单。一个订单有多个产品。一个客户有多个取消。取消有多个productContainers。productContainer有一个产品 问题 我想获得所有未取消的订购产品 $qb->select('c, d, p') ->from('XyzBundle:Customer', 'c') ->leftJoin('c.orders', 'co') -&g

使用dql,我试图检查一个实体是否是集合子实体的成员

实体: 一个客户有多个订单。一个订单有多个产品。一个客户有多个取消。取消有多个productContainers。productContainer有一个产品

问题 我想获得所有未取消的订购产品

       $qb->select('c, d, p')
       ->from('XyzBundle:Customer', 'c')
       ->leftJoin('c.orders', 'co')
       ->leftJoin('co.products', 'cop')
       ->leftJoin('c.cancellation', 'ca')
       ->leftJoin('ca.productContainers', 'cap')
       ->leftJoin('cap.product', 'capp')
       ->andWhere('cop NOT MEMBER OF capp')
但是,这不起作用,因为ca.productContainers是集合字段,而不是其supentity ca.productContainers.product。因此,我得到以下错误:

       CRITICAL - Uncaught PHP Exception Doctrine\ORM\Query\QueryException: 
       "[Semantical Error] line 0, col 414 near 'product': Error: Invalid PathExpression. 
       Must be a CollectionValuedAssociationField." at 
       /vagrant/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php line 4 9
有什么建议可以解决这个问题吗

我想获得所有未取消的订购产品

       $qb->select('c, d, p')
       ->from('XyzBundle:Customer', 'c')
       ->leftJoin('c.orders', 'co')
       ->leftJoin('co.products', 'cop')
       ->leftJoin('c.cancellation', 'ca')
       ->leftJoin('ca.productContainers', 'cap')
       ->leftJoin('cap.product', 'capp')
       ->andWhere('cop NOT MEMBER OF capp')
假设
  • 您需要这些产品以及客户名称
  • 一个订单有多个产品
  • productContainer具有一个产品,而不是多个产品
-

通过考虑上述假设,您可以编写以下DQL来获得您的产品

SELECT c,cop.product /* cop.product => refers to property which has an association with product entity */
FROM XyzBundle:Customer c
    LEFT JOIN c.orders co
    LEFT JOIN co.products cop
    LEFT JOIN c.cancellation ca
    LEFT ca.productContainers cap
    LEFT cap.product capp WITH capp.product = cop.product
WHERE capp.product IS NULL
在查询生成器之后,您可以添加一个带有部分的
,该部分将作为连接子句的另一个条件,如a=b和(带有)c=d上的
,因此对于带有capp.product=cop.product的
,它将取消productContainers产品与附加子句连接,并关联产品记录。因此,要过滤掉取消的产品,您可以将其写为
cap.product
,即(取消产品容器)应为空

如果您只需要产品信息而不需要其他详细信息,可以使用更简单的版本

SELECT p
FROM XyzBundle:Product p
    LEFT JOIN XyzBundle:ProductContainers pc WITH p.id = pc.product
WHERE pc.product IS NULL
上述DQL将生成以下等效SQL

SELECT p.*
FROM product p
    LEFT JOIN product_containers pc ON p.id = pc.product_id
WHERE pc.product_id IS NULL
另一种将DQL重写为

SELECT p,c
FROM XyzBundle:Product p
    LEFT JOIN XyzBundle:ProductContainers pc WITH p.id = pc.product
    INNER JOIN XyzBundle:OrderProducts op WITH p.id = op.product
    INNER JOIN op.order o /* property in XyzBundle:OrderProducts which has a reference to order entity */
    INNER JOIN o.customer c /* property in order entity which has a reference to customer entity */
WHERE pc.product IS NULL

我用两个查询解决了这个问题,但记不清了。