如何工作createQueryBuilder和leftJoin?

时间:2013-03-21 15:57:17

标签: doctrine-orm

我不知道如何让它发挥作用。

我有:

  • 包含字段partnerid
  • 的表格name
  • 包含两个字段的表partner_addressid_partnerid_address
  • 包含字段address和外部密钥id的表id_town,引用town(id)
  • 包含字段townidname
  • 的表postal_code

我想选择具有特定postal_code的城镇中的所有合作伙伴 此查询有效:

SELECT p.nom, v.nom
FROM partner p
JOIN partner_address pa
ON pa.id_partner=p.id
JOIN address a
ON pa.id_address = a.id 
JOIN town t
ON a.id_town=t.id
WHERE t.postal_code='13480';

现在,我希望在the documentation之后将其“翻译”为Doctrine 2完整语法。

所以我创建了一个自定义存储库:

src/Society/Bundle/MyProjectBundle/Repository/PartnerRepository.php

在这个存储库中,我正在尝试创建相应的函数:

<?php

namespace HQF\Bundle\PizzasBundle\Repository;

use Doctrine\ORM\EntityRepository;

class PartenaireRepository extends EntityRepository
{
    /**
     * Get all active partners from a given postal code.
     */
    public function findAllActiveByCp($cp)
    {
        return $this->createQueryBuilder('p')
            ->where('p.dateVFin IS NULL')
            ->andWhere('p.cp=:cp')
            ->addOrderBy('p.cp', 'DESC')
            ->setParameter('cp', $cp);
    }
}

Nota:代码中的查询不是正确的,但此代码适用于我制作的另一个自定义存储库,因此我尝试从此代码开始。

我正在尝试这样的事情,但它不起作用:

public function findAllActiveByCp($cp)
{
    $qb = $this->createQueryBuilder('p');
    return $qb
        ->leftJoin('partner_address pa ON pa.id_partner=p.id')
        ->leftJoin('address a ON pa.id_address = a.id')
        ->leftJoin('town t ON a.id_ville=t.id')
        ->where('p.dateVFin IS NULL')
        ->andWhere('t.cp=:cp')
        ->addOrderBy('t.cp', 'DESC')
        ->setParameter('cp', $cp);
}

我收到此错误:

  

警告:缺少Doctrine \ ORM \ QueryBuilder :: leftJoin()的参数2,   呼唤   /blabla/Repository/PartenaireRepository.php   在第18行并在中定义   /blabla/symfony/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php   第767行

2 个答案:

答案 0 :(得分:7)

您必须仅加入所选实体所拥有的属性。

join()leftJoin()xxxJoin()的第一个参数中,您传递与所选对象相关的属性名称,以及第二个 - 已加入实体的别名。

尝试simmilar:

$q = $this->em()->createQueryBuilder();

$q->select(['item', 'itemContact'])
  ->from('ModuleAdmin\Entity\CustomerEntity', 'item')
  ->leftJoin('item.contacts', 'itemContact')
  ->andWhere($q->expr()->like('item.name', ':customerNameStart'));

当然,CustomerEntity字段OneToMany中包含contacts关系。

请记住,在select语句中,您必须选择根实体(在我的示例CustomerEntity别名为item)。


由Olivier Pons编辑添加我如何找到解决方案,并将此答案标记为有效,因为它让我走上了正确的轨道,谢谢Adam!

在文件PartenaireRepository.php中,我已正确使用createQueryBuilder('p')。以下是使用createQueryBuilder()

连续创建两个连接的方法
class PartenaireRepository extends EntityRepository
{

    /** 
     * Récupération de tous les partenaires donnés pour un
     * code postal donné.
     */
    public function findAllActiveByCp($cp)
    {   
        return $this->createQueryBuilder('p')
            ->leftJoin('p.adresses', 'a')
            ->leftJoin('a.ville', 'v')
            ->where('v.cp=:cp')
            ->setParameter('cp', $cp);
    ... blabla
    }
}

答案 1 :(得分:0)

我相信你正在做的事情,你需要为leftJoin方法提供四个参数。

->leftJoin('partner_address', 'pa', 'ON', 'pa.id_partner = p.id')

因此,您的查询构建器链应该如下所示

public function findAllActiveByCp($cp)
{
    $qb = $this->createQueryBuilder('p');
    return $qb
        ->leftJoin('partner_address', 'pa', 'ON', 'pa.id_partner = p.id')
        ->leftJoin('address', 'a', 'ON', 'pa.id_address = a.id')
        ->leftJoin('town', 't', 'ON', 'a.id_ville = t.id')
        ->where('p.dateVFin IS NULL')
        ->andWhere('t.cp=:cp')
        ->addOrderBy('t.cp', 'DESC')
        ->setParameter('cp', $cp)
    ;
}
相关问题