2013-06-25 9 views
8

Ich versuche, die Lehre Querybuilder zu verwenden, um die folgende SQL-Abfrage auszuführen:Lehre Querybuilder löschen mit Verknüpfungen

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

Ich habe diese

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

aber ich bekomme:

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

Der DQL, der mit der Fehlermeldung geliefert wird, lautet:

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

So scheinen die Joins komplett ausgelassen zu werden.

Antwort

8

Ein Weg dies zu tun könnte sein, zuerst die Entitäten Sie die Verknüpfungen löschen möchten Abfrage:

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

und löschen Sie die Objekte, die Sie im Ergebnis gefunden:

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

Be sicher anzurufen

$this->entityManager->flush(); 

an der entsprechenden Stelle in Ihrer Anwendung (in der Regel der Controller).

+1

Nur zwei Dinge zu erwähnen. 1. Dies kann sehr teuer sein. 2. Wage es nicht, eine solche Logik in einen Controller zu stecken! – EnchanterIO

+2

3. Sache - Dies ist anfällig für Race-Bedingungen. – Kaspars

7

Es sieht so aus, als ob DQL diese Art von Löschanweisung nicht unterstützt. Die BNF from the Doctrine documentation zeigt an, dass ein delete_statement die Form muss

delete_clause [where_clause] 

Wo delete_clause wie folgt definiert ist:

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

So kann ich ein Schema zur Verfügung stellen und eine where-Klausel, aber nicht beitritt.

-2

Auf Symfony2 bitte versuchen Sie es:

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

$em->flush(); 

Das ist alles.

+0

In Fällen, in denen Sie ein nuancierteres Löschen benötigen (z. B. die ursprüngliche Frage), funktioniert diese Standardmethode "$ em-> remove ($ entity)" nicht. –