2013-06-25 2 views
8

Я пытаюсь использовать Doctrine QueryBuilder выполнить следующий SQL-запрос:Доктрина QueryBuilder удалить с соединениями

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'; 

Я это

$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(); 

, но я получаю:

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

DQL, который поставляется с сообщением об ошибке:

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

Таким образом, соединения, кажется, полностью исключены.

ответ

8

способ сделать это может быть первый запрос примитивов, которые вы хотите удалить, используя стыки:

$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(); 

И затем удалить объекты, которые вы нашли в результате:

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

Ве Обязательно позвоните по телефону

$this->entityManager->flush(); 

в соответствующем месте вашего приложения (как правило, контроллер).

+1

Только две вещи, которые следует упомянуть. 1. Это может быть очень дорого. 2. Не смей вводить такую ​​логику в контроллер! – EnchanterIO

+2

Третья вещь - это склонно к условиям гонки. – Kaspars

7

Похоже, что DQL не поддерживает этот вид инструкции удаления. BNF from the Doctrine documentation указывает на то, что delete_statement должен принять форму

delete_clause [where_clause] 

Где delete_clause не определяется как:

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

Так что я могу предоставить схему и где положение, но не присоединяется.

-2

На Symfony2, пожалуйста, попробуйте:

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

$em->flush(); 

Вот и все.

+0

В случае, если вам требуется более тонкое удаление (например, исходный вопрос), этот метод '$ em-> remove ($ entity)' по умолчанию не будет работать. –