题 Symfony2 QueryBuilder加入ON和WITH区别


我是Symfony2的新手,我通过QueryBuilder和Doctrine 2成功构建了我的第一个连接。 可能这是一个愚蠢的问题但是在线和Symfony2的方法中我都无法找到任何理解连接子句“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子句,但是它们的使用区别是什么?他们的用途是什么样的?


27
2017-07-02 09:58


起源


根本不是一个愚蠢的问题。这是Doctrine文档的主要问题。没有参考,只有参考指南没有涵盖这个和许多其他不清楚。 - agoldev


答案:


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

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

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

(或类似的东西)

现在在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

在学说中:

// 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() ;
}

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


43
2017-07-02 14:44



结果怎么样?它返回关联的实体\模型?例如,我无法得到合适的 stackoverflow.com/questions/20134014/... - user1954544
派对有点晚了,但联接查询方法在哪里适当放置?在上面的示例中,您在中创建了查询方法 CategoryRepository.php 为什么不呢 ProductRepository.php?? - Sanjok Gurung


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

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

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

doctrine2将正确处理连接。

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


6
2017-07-02 11:51



非常感谢您的评论。我已经看过那个帖子和我的问题是它不能满足我的问题因为那里,只写了解决方案而不是“WITH”而不是“OR”的原因和它们的区别。 - Roberto Rizzi