我尝试在我的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;
有什么问题?
答案 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中