web-dev-qa-db-ja.com

Symfony2 QueryBuilderは、ONとWITHの違いに参加します

私はSymfony2を初めて使用し、QueryBuilderとDoctrine 2.を使用して最初の結合を正常に作成しました。結合句「WITH」と「ON」の違いを理解するため。

たとえば、これは私の結合コードです:

->leftJoin('EcommerceProductBundle:ProductData', 'pdata', 'WITH', 'prod.id = IDENTITY(pdata.product)')

うまくいきますが、ONの代わりにWITHを配置すると、次のエラーが表示されます。

[構文エラー]行0、列200:エラー:Doctrine\ORM\Query\Lexer :: T_WITHが期待され、 'ON'になりました

どうして?オブジェクト間で、T_ONとT_WITHのようなjoin句の両方があることを見てきましたが、使用法の違いはどれですか?それらの用途はどのようなものですか?

31
Roberto Rizzi

@florianはあなたに正しい答えを与えましたが、例を挙げて説明してみましょう:

SQLでは、結合は次のように行われます。

SELECT * FROM category
    LEFT JOIN product ON product.category_id = category.id

(またはこのようなもの)

Doctrineでは、doctrineはエンティティのリレーションアノテーションからそれを知っているため、ON句を使用する必要はありません。上の例は次のようになります。

// CategoryRepository.php
public function getCategoriesAndJoinProducts() 
{
    return $this->createQueryBuilder("o")
        ->leftJoin("o.products", "p")->addSelect("p") 
        ->getQuery()->getResult() ;
}

両方ともすべてのカテゴリを取得し、それらに関連付けられた製品を結合します。

WITH句が追加されました。 50を超える価格の製品のみに参加する場合は、SQLでこれを行います。

SELECT * FROM category
    LEFT JOIN product ON product.category_id = category.id AND product.price>50

Doctrineの場合:

// CategoryRepository.php
public function getCategoriesAndJoinProductsWithPriceBiggerThan($price) 
{
    return $this->createQueryBuilder("o")
        ->leftJoin("o.products", "p", "WITH", "p.price>:price")
            ->setParameter("price", price)->addSelect("p") 
        ->getQuery()->getResult() ;
}

したがって、Doctrineを使用している場合、実際にはONを使用しないでください。そのようなものが必要な場合、他の何かをねじ込んだことはほぼ確実です。

48
Zeljko

理論的には、ONでは完全な結合条件を指定できますが、WITHでは追加の条件をデフォルトの条件(IMHO)に追加できます。

しかし、DQLが許可するのは、JOIN基準を与えることを避けることです。

言う必要があります:$qb->leftJoin('prod.pdata', 'pdata');

そして、Doctrine2は結合を正しく処理します。

関連する質問は次のとおりです。 DQLで「ON」キーワードを使用できますか、またはネイティブクエリを使用する必要がありますか?

7
Florian