Doctrine orm createQueryBuilder和leftJoin如何工作?

Doctrine orm createQueryBuilder和leftJoin如何工作?,doctrine-orm,Doctrine Orm,我不知道如何使它工作 我有: 带有字段id和name 表partner\u address,包含两个字段:id\u partner和id\u address 带有字段id和外部键id\u town的表address,其中引用town(id) 带有字段id、名称和邮政编码的表town 我要选择位于具有特定邮政编码的城镇的所有合作伙伴 此查询可用于: SELECT p.nom, v.nom FROM partner p JOIN partner_address pa ON pa.id_partn

我不知道如何使它工作

我有:

  • 带有字段
    id
    name
  • partner\u address
    ,包含两个字段:
    id\u partner
    id\u address
  • 带有字段
    id
    和外部键
    id\u town
    的表
    address
    ,其中引用
    town(id)
  • 带有字段
    id
    、名称
    和邮政编码
    的表
    town
我要选择位于具有特定邮政编码的城镇的所有合作伙伴 此查询可用于:

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';
现在我想把它“翻译”成条令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);
    }
}
我得到这个错误:

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


我相信对于您正在做的事情,您需要为
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)
    ;
}

我相信对于您正在做的事情,您需要为
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)
    ;
}

必须仅连接选定实体具有的属性

join()
leftJoin()
xxxJoin()
的第一个参数中,传递与选定对象相关的属性名称,并在第二个参数中传递连接实体的别名

尝试类似的方法:

$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
关系

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


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

在文件
PartenaireRepository.php
中,我正确地使用了
createQueryBuilder('p')
。下面是如何使用
createQueryBuilder()
在一行中创建两个联接:


必须仅连接选定实体具有的属性

join()
leftJoin()
xxxJoin()
的第一个参数中,传递与选定对象相关的属性名称,并在第二个参数中传递连接实体的别名

尝试类似的方法:

$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
关系

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


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

在文件
PartenaireRepository.php
中,我正确地使用了
createQueryBuilder('p')
。下面是如何使用
createQueryBuilder()
在一行中创建两个联接:


我尝试过,但在
->leftJoin('partner\u address')
[语义错误]第0行,第68列“partner\u address”附近出现错误:错误:未定义类“partner\u address”。
。我不明白。为什么它应该是一个“类”?它应该是一个数据库表,故事结束了!啊,每个表都有条令实体类吗?也就是说,是否存在映射到
合作伙伴地址表的
HQF\Bundle\PizzasBundle\Entity\PartnerAddress
?如果是这样,用
PartnerAddress
替换
PartnerAddress
。是的,我有点同意,它应该是一个表而不是一个类,但我想这就是它被称为ORM的原因。如果您喜欢使用QueryBuilder,但直接与表一起使用,DBAL中有一个可用,但没有ORM中的所有功能。另一个问题是表
partner\u address
已在实体
partner
php文件的属性
addresses
中声明(这是一个
@ORM\manytomy(targetEntity=“Address”)
属性)。这让我很紧张,因为做同一件事有不同的方法,而且从来都不清楚哪种方法是最好的。也许我应该这样做
findAllActiveByCp($cp)
Town
实体,并创建类似于
findAllActivePartnersByCp($cp)
之类的东西……我已经尝试过了,但是
->leftJoin('partner\u address')上出现错误。
[语义错误]第0行,第68列“partner\u address”附近:错误:未定义类“partner\u address”。
。我不明白。为什么它应该是“类”它应该是一个数据库表,故事的结尾!啊,每个表都有一个条令实体类吗?也就是说,是否有一个
HQF\Bundle\PizzasBundle\entity\PartnerAddress
映射到
partner\u address
表?如果有,用
PartnerAddress
替换
partner\u address
。是的,我有点同意,它应该是一个表,而不是类,但我想这就是为什么它被称为ORM的原因。如果您更喜欢使用QueryBuilder,但直接与表一起使用,DBAL中有一个可用,但没有ORM中的所有功能。另一个问题是,表
partner\u address
已在实体
partner
php中声明文件,在属性
地址中(这是一个
@ORM\manytomy(targetEntity=“Address”)
属性)。这让我很不安,因为有不同的方法来做