2013-06-25 12 views
8

sto cercando di usare la dottrina QueryBuilder per eseguire la seguente query SQL:Dottrina QueryBuilder cancellare con unisce

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

ho questo

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

ma ottengo:

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

Il DQL fornito con il messaggio di errore è:

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

Quindi i join sembrano essere completamente omessi.

risposta

8

Un modo per raggiungere questo obiettivo potrebbe essere quello di interrogare prima le entità che si desidera eliminare utilizzando i join:

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

e quindi eliminare le entità che hai trovato nel risultato:

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

Be sicuro di chiamare

$this->entityManager->flush(); 

nel punto appropriato dell'applicazione (in genere il controller).

+1

Solo due cose da menzionare. 1. Questo può essere molto costoso. 2. Non osare mettere una tale logica in un controller! – EnchanterIO

+2

Terza cosa - Questo è soggetto alle condizioni di gara. – Kaspars

7

Sembra che DQL non supporti questo tipo di istruzione di eliminazione. Il BNF from the Doctrine documentation indica che un delete_statement deve assumere la forma

delete_clause [where_clause] 

Dove delete_clause è definito come:

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

Così posso fornire uno schema e una clausola in cui, ma non si unisce.

-2

Su Symfony2 riprova:

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

$em->flush(); 

Questo è tutto.

+0

Nei casi in cui è necessaria una cancellazione più sfumata (ad esempio la domanda originale), questo metodo predefinito $ $ em-> remove ($ entity) 'non funzionerà. –