Doctrine 2 JOIN ON错误

时间:2012-01-20 09:24:18

标签: join doctrine-orm dql

我尝试在我的CompanyRepository

中执行此查询
$qb = $this->_em->createQueryBuilder();
$qb->select(array('c', 'ld'))
        ->from('Model\Entity\Company', 'c')
        ->leftJoin('c.legaldetails', 'ld', \Doctrine\ORM\Query\Expr\Join::ON, 'c.companyid=ld.companyid');

$query = $qb->getQuery();
echo($query->getSQL());

当我尝试这样做时,我有错误:

致命错误:未捕获的异常' Doctrine \ ORM \ Query \ QueryException'消息' [语法错误]第0行,第69列:错误:字符串的预期结束,得到' ON''在/home/raccoon/web/freetopay.dev/www/class/new/library/Doctrine/ORM/Query/QueryException.php第42行

这些是我的模特:

<?php    
namespace Model\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Company
 *
 * @ORM\Table(name="Company")
 * @ORM\Entity(repositoryClass="\Model\Repository\CompanyRepository")
 */
class Company
{
/**
 * @var integer $companyid
 *
 * @ORM\Column(name="CompanyID", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $companyid;

/**
 * @var \Model\Entity\LegalDetails $legaldetails
 *
 * @ORM\OneToOne(targetEntity="\Model\Entity\Legaldetails", mappedBy="companyid")
 */
private $legaldetails;

//other fields

public function __construct()
{
    $this->legaldetails = new ArrayCollection();
}    

//setters and getters

和legaldetails实体:

<?php
namespace Model\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Legaldetails
 *
 * @ORM\Table(name="LegalDetails")
 * @ORM\Entity
 */
class Legaldetails
{
/**
 * @var integer $legalid
 *
 * @ORM\Column(name="LegalID", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $legalid;

/**
 * @var \Model\Entity\Company $company
 *
 * @ORM\Column(name="CompanyID", type="integer", nullable=false)
 * @ORM\OneToOne(targetEntity="\Model\Entity\Company", inversedBy="companyid")
 * @ORM\JoinColumn(name="companyid", referencedColumnName="companyid")
 */
private $company;

有什么问题?

3 个答案:

答案 0 :(得分:20)

对于那些来到这里的问题是“预期结束字符串,得到'ON'”,但找不到正确的答案,因为我不能(嗯,有答案,但不完全是关于QueryBuilder )。通常,是的,您不需要指定连接列。但是如果你需要添加额外的过滤呢。例如,我希望添加一个额外的条件(允许在连接中使用空值)。

这里的问题是,即使常量Join :: ON存在(并且Join表达式中的注释也提到它),DQL中没有ON。相反,应该使用WITH(Join :: WITH)。

这是我的用法示例:

$qb->leftJoin('p.metadata', 'm', Join::WITH, "IFNULL(m.name, '') = 'email'");

P.S。预测有关IFNULL()的问题 - 它是Benjamin Eberlei's Doctrine extension

答案 1 :(得分:2)

关于JOIN如何使用DQL here,有一个非常明确的解释:

  

使用DQL编写连接时,它可以是过滤连接(类似于用于限制或聚合结果的SQL连接的概念)或提取连接(用于获取相关记录并将其包含在结果中)主要查询)。当您在SELECT子句中包含来自联接实体的字段时,您将获得一个获取连接

这应该足以得到你想要的东西(关于所有加载了法律信息的公司的信息):

$query = $em->createQuery('SELECT c, ld FROM \Model\Entity\Company c JOIN c.legaldetails ld');
$companies = $query->getResult(); // array of Company objects with the legaldetails association loaded

修改

我在查询中使用了常规联接,因此查询中不会返回没有合法信息的公司。如果您想要所有公司,即使他们没有加载任何法律信息,您也应该尝试使用左边的连接

答案 2 :(得分:1)

我们都考虑过SQL。但是在DQL WITH中使用而不是ON。 example

编辑: 如果您了解SQL,为什么不使用查询,例如:

    $query = $this->getEntityManager()->createQuery('
        SELECT t...
    ');

把你认为应该存在的SQL放在那里,检查一下。如果它可以工作 - 问题出在Doctrine代码中,如果没有 - 错误在SQL / DQL中