Doctrine QueryBuilder delete with joins

余生长醉 提交于 2019-11-27 04:49:26

问题


I'm trying to use the Doctrine QueryBuilder to perform the following SQL query:

DELETE php FROM product_hole_pattern php
INNER JOIN hole_pattern hp ON php.hole_pattern_id = hp.id
INNER JOIN hole_pattern_type hpt ON hp.hole_pattern_type_id = hpt.id
WHERE php.product_id = 4 AND hpt.slug='universal';

I have this

$qb = $this->entityManager->createQueryBuilder();
$query = $qb->delete('\SANUS\Entity\ProductHolePattern', 'php')
  ->innerJoin('php.holePattern', 'hp')
  ->innerJoin('hp.holePatternType', 'hpt')
  ->where('hpt.slug = :slug AND php.product=:product')
  ->setParameter('slug','universal')
  ->setParameter('product',$this->id)
  ->getQuery();

but I get:

[Semantical Error] line 0, col 50 near 'hpt.slug = :slug': Error: 'hpt' is not defined.

The DQL that comes with the error message is:

DELETE \SANUS\Entity\ProductHolePattern php 
WHERE hpt.slug = :slug AND php.product=:product

So the joins seem to be omitted completely.


回答1:


It may be better to run a query with IN condition rather than iterating.

$ids = $this->createQueryBuilder('product')
->join('..your joins..')
->where('..your wheres..')
->select('product.id')
->getQuery()->getResult();

$this->createQueryBuilder('product')
    ->where('product.id in (:ids)')
    ->setParameter('ids', $ids)
    ->delete()
    ->getQuery()
    ->execute();
  • Benefits: runs faster, no need to iterate
  • Drawbacks: you can't hook into preRemove

As to heated "where to put it" debate, dare to put it in the controller if you like. That's completely up to you. However, it may be more useful to you in the future if you land the code in the dedicated doctrine repository class. It should be very easy to do and makes it easy to change / maintain.




回答2:


It looks like DQL doesn't support this sort of delete statement. The BNF from the Doctrine documentation indicates that a delete_statement must take the form

delete_clause [where_clause]

Where delete_clause is defined as:

"DELETE" "FROM" abstract_schema_name [["AS"] identification_variable]

So I can provide a schema and a where clause, but no joins.




回答3:


A way to accomplish this might be to first query the entities you want to delete using the joins:

$qb = $this->entityManager->createQueryBuilder();
$query = $qb->select('\SANUS\Entity\ProductHolePattern', 'php')
  ->innerJoin('php.holePattern', 'hp')
  ->innerJoin('hp.holePatternType', 'hpt')
  ->where('hpt.slug = :slug AND php.product=:product')
  ->setParameter('slug','universal')
  ->setParameter('product',$this->id)
  ->getQuery();
$results = $query->execute();

And then delete the entities you found in the result:

foreach ($results as $result) {
  $this->entityManager->remove($result);
}

Be sure to call

$this->entityManager->flush();

at the appropriate place in your application (typically the controller).




回答4:


On Symfony2 please try:

foreach ($results as $result) {
  $em->remove($result);
}

$em->flush();

Thats all.



来源:https://stackoverflow.com/questions/17301636/doctrine-querybuilder-delete-with-joins

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!