使用dql我试图检查实体是否是集合子实体的成员
product
customer
customer.orders (collection)
customer.orders.products (collection, type: product)
customer.cancellations.productContainers (collection)
customer.cancellations.productContainers.product (entity, type: product)
Run Code Online (Sandbox Code Playgroud)
客户有多个订单.订单有多个产品.客户有多次取消.取消有多个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')
Run Code Online (Sandbox Code Playgroud)
但是这不起作用,因为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
Run Code Online (Sandbox Code Playgroud)
有什么建议如何解决这个问题?
我想获取所有未取消的已订购产品。
-
通过考虑上述假设,您可以编写以下 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
Run Code Online (Sandbox Code Playgroud)
在您的查询构建器之后,您可以添加一个WITH部分,该部分将充当 JOIN 子句的另一个条件,例如ON a=b AND (WITH) c=dSo 因为WITH capp.product = cop.product它将取消 ProductContainers 产品与附加子句连接起来并关联产品记录。因此,要过滤掉已取消的产品,您可以将其编写为cap.productie (取消产品容器) 应该为 null。
如果您只需要产品信息而不需要其他详细信息,您可以使用更简单的版本
SELECT p
FROM XyzBundle:Product p
LEFT JOIN XyzBundle:ProductContainers pc WITH p.id = pc.product
WHERE pc.product IS NULL
Run Code Online (Sandbox Code Playgroud)
上面的 DQL 将生成以下等效的 SQL
SELECT p.*
FROM product p
LEFT JOIN product_containers pc ON p.id = pc.product_id
WHERE pc.product_id IS NULL
Run Code Online (Sandbox Code Playgroud)
将 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
895 次 |
| 最近记录: |