Doctrine QueryBuilderを使用して、次のSQLクエリを実行しようとしています。
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
したがって、結合は完全に省略されているようです。
反復するよりも、IN条件でクエリを実行する方がよい場合があります。
$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();
「どこに置くか」という白熱した議論については、必要に応じてあえてコントローラーに入れてください。それは完全にあなた次第です。ただし、コードを専用のdoctrineリポジトリクラスに配置すると、将来的にはさらに便利になる可能性があります。これは非常に簡単で、変更/保守も簡単です。
DQLはこの種の削除ステートメントをサポートしていないようです。 Doctrineドキュメント からのBNFは、delete_statement
形式をとる必要があります
delete_clause [where_clause]
どこ delete_clause
と定義されている:
"DELETE" "FROM" abstract_schema_name [["AS"] identification_variable]
したがって、スキーマとwhere句を提供できますが、結合は提供できません。
これを実現する方法は、最初に結合を使用して削除するエンティティをクエリすることです。
$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();
アプリケーションの適切な場所(通常はコントローラー)。