带有教义的查询构建器中的外部联接
Posted
技术标签:
【中文标题】带有教义的查询构建器中的外部联接【英文标题】:outer join in a query builder with doctrine 【发布时间】:2015-09-10 08:40:25 【问题描述】:我有一个名为 PointsComptage.php
的实体和另一个名为 Compteurs.php
的实体。
这是它们之间的关系:
// Compteurs.php
/**
* @var \PointsComptage
*
* @ORM\ManyToOne(targetEntity="PointsComptage", inversedBy="compteurs")
* @ORM\JoinColumns(
* @ORM\JoinColumn(name="pointscomptage_id", referencedColumnName="id")
* )
*/
private $pointsComptage;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="ParametresMesure", mappedBy="compteurs")
*/
private $parametresMesure;
/* ... */
// PointsComptage.php
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Compteurs", mappedBy="pointsComptage")
*/
private $compteurs;
/* ... */
这是我的存储库实体中的查询,用于恢复具有某一点Comptage 属性的compteurs:
$queryBuilder = $this->_em->createQueryBuilder();
$queryBuilder
->select ('c')
->from('MySpaceMyBundle:Compteurs', 'c')
->leftJoin('c.pointsComptage', 'pc')
->join('c.parametresMesure', 'pm')
->join('pm.typesUnite', 'tu')
->join('pm.typesParametre', 'tp')
->where('c.pointsComptage = pc.id')
->andWhere('pm.compteurs = c.id')
->andWhere('pm.typesUnite = tu.id')
->andWhere('pm.typesParametre = tp.id')
->andWhere('c.pointsComptage = :id')
->add('orderBy', 'c.miseEnService', 'ASC')
->setParameter('id', $id);
return $queryBuilder->getQuery()
->getResult();
问题是我为所选的 pointComptage 恢复了我的compteurs,但只有具有parametresMesure 关系的compteurs。
在我的数据库中,可能一个compteur 没有 parametreMesure 数据。
如何恢复没有parametresMesure的compteurs和有parametresMesure属性的compteurs(在同一个queryBuilder中)?
我在教义文档中读到,queryBuilder 中的 leftJoin 的工作方式类似于外连接。
我正在尝试做的是恢复与所选pointComptage
相关联的所有compteurs
,无论parametresMesure
是否。
【问题讨论】:
如果您在 SO 中搜索“教条外连接”,则有几个答案。其中之一几乎肯定会对您有所帮助。 只需使用leftJoin
而不是join
@PiWi 即使我在 queryBuilder 中使用 leftJoin
而不是 join
,我的请求也会返回相同的结果,即只有具有 parametresMesure 的 compteurs ,但是对于之前选择的 pointComptage,我有一个没有 parametresMesure 的 compteur。
【参考方案1】:
我找到了解决方案。问题是我在Where
子句中添加了条件,但我需要在leftJoin
中指定它们。
这是我的代码以了解我所做的事情:
$queryBuilder = $this->_em->createQueryBuilder();
$queryBuilder
->select ('c')
->from('MySpaceMyBundle:Compteurs', 'c')
->leftJoin('c.pointsComptage', 'pc', 'WITH', 'pc.id = c.pointsComptage')
->leftJoin('c.parametresMesure', 'pm', 'WITH', 'pm.compteurs = c.id')
->leftJoin('pm.typesUnite', 'tu', 'WITH', 'pm.typesUnite = tu.id')
->leftJoin('pm.typesParametre', 'tp', 'WITH', 'pm.typesParametre = tp.id')
->andWhere('c.pointsComptage = :id')
->add('orderBy', 'c.miseEnService', 'ASC')
->setParameter('id', $id);
return $queryBuilder->getQuery()
->getResult();
这样我恢复了我所有的compteurs
,即使他们没有parametresMesure
。
【讨论】:
你自己找到的 :-) 我只是在自己写这个答案 ;-) 如果你使用左连接,这比最终的过滤效果更好。 你能解释一下为什么我们不使用 ->Having('pc.id = c.pointsComptage') 来代替 WITH 吗?以上是关于带有教义的查询构建器中的外部联接的主要内容,如果未能解决你的问题,请参考以下文章
将带有变量的闭包传递给 Laravel 查询构建器中的 where 方法