Symfony2 QueryBuilder加入ON和WITH区别

Rob*_*zzi 33 left-join query-builder symfony doctrine-orm

我是Symfony2的新手,我通过QueryBuilder和Doctrine 2成功构建了我的第一个连接.可能这是一个愚蠢的问题但是在线和Symfony2的方法中我都无法找到任何理解join子句之间的区别的东西"用"和"开".

例如,这是我的加入代码:

->leftJoin('EcommerceProductBundle:ProductData', 'pdata', 'WITH', 'prod.id = IDENTITY(pdata.product)')
Run Code Online (Sandbox Code Playgroud)

它工作正常,但如果我把ON而不是WITH我得到以下错误:

[语法错误]第0行,第200行:错误:预期的Doctrine\ORM\Query\Lexer :: T_WITH,得到'ON'

为什么?我在对象中看到T_ON和T_WITH都有join子句,但是它们的使用区别是什么?他们的用途是什么样的?

Zel*_*jko 51

@florian给了你正确的答案,但让我试着在例子中解释它:

在sql中,连接是这样完成的:

SELECT * FROM category
    LEFT JOIN product ON product.category_id = category.id
Run Code Online (Sandbox Code Playgroud)

(或类似的东西)

现在在Doctrine中,您不需要使用ON子句,因为doctrine知道您实体中的关系注释.所以上面的例子是:

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

两者都将获取所有类别并加入与其关联的产品.

现在是WITH条款.如果您只想加入价格大于50的产品,您可以在SQL中执行此操作:

SELECT * FROM category
    LEFT JOIN product ON product.category_id = category.id AND product.price>50
Run Code Online (Sandbox Code Playgroud)

在学说中:

// 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() ;
}
Run Code Online (Sandbox Code Playgroud)

所以,实际上ON如果你使用的是Doctrine ,你永远不应该使用它.如果你需要这样的东西,你几乎可以肯定你搞砸了别的东西.


Flo*_*ian 7

理论上,ON允许您提供完整的连接标准,而WITH允许在默认值(IMHO)中添加其他标准.

但是,DQL允许的是避免给出JOIN标准:

你只需要说: $qb->leftJoin('prod.pdata', 'pdata');

doctrine2将正确处理连接.

这是一个相关的问题:我可以在DQL中使用"ON"关键字,还是需要使用Native Query?