我试图弄清楚如何连接两个表,同时查询第二个表。我觉得它很简单:
// Within ServerServiceRepository
return $this->createQueryBuilder('ss')
->join(ServiceType::class, 't')
->where('t.serviceTypeName = :name')
->getQuery()
->execute(['name' => $name]);
但事实证明,并非如此......
问题是查询没有加入密钥(两个表上的service_type_id)。这里发生了什么?我正确设置了所有OneToMany关系:
/**
* ServerService
*
* @ORM\Table(name="server_services")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ServerServiceRepository")
*/
class ServerService extends AbstractEntity
{
/**
* @var ServiceType
*
* @ORM\Column(name="service_type_id", type="integer", nullable=false)
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Supportal\ServiceType", fetch="LAZY", inversedBy="serviceTypeId")
* @ORM\JoinColumn(name="service_type_id", referencedColumnName="service_type_id")
*/
private $serviceType;
// [...]
}
/**
* ServiceType
*
* @ORM\Table(name="service_types")
* @ORM\Entity
*/
class ServiceType extends \AppBundle\Entity\AbstractEntity
{
/**
* @var integer
*
* @ORM\Column(name="service_type_id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
* @ORM\OneToMany(targetEntity="AppBundle\Entity\ServerService", fetch="EXTRA_LAZY", mappedBy="serviceType")
*/
private $serviceTypeId;
/**
* @var string
*
* @ORM\Column(name="service_type_name", type="string", length=255, nullable=true)
*/
private $serviceTypeName;
// [...]
}
我已将ServiceT中的OneToMany关系添加/删除为无更改。这实际上是一个单向关系。根据Doc Doctrine自己的文档(第5章),ServerType 不需要关系映射。
SQL查询正在生成缺少实际密钥的JOIN:
INNER JOIN service_types s1_ ON (s1_.service_type_name = ?)
为了让这项工作正常,我在学说中缺少什么?我看过这些教程。 Symofny的例子几乎就是我所追求的,除了我需要选择"类别名称"不是产品ID:https://symfony.com/doc/2.8/doctrine/associations.html
我必须错过一些非常简单的东西。但我不能为我的生活而盯住它......
修改
我已在代码中从ServiceType中删除了OneToMany。它是可选的。反正不需要这个。这是单向关系。
我试过这个:
return $this->createQueryBuilder('ss')
->join('ss.serviceType', 't')
->where('t.serviceTypeName = :name')
->getQuery()
->execute(['name' => $name]);
导致此错误:
[Semantical Error] line 0, col 85 near 't WHERE t.serviceTypeName': Error: Class AppBundle\Entity\ServerService has no association named serviceType
解决方案
解决方案是删除@ORM Column
定义。看起来它是关系定义中的冲突。
答案 0 :(得分:0)
首先,将 ManyToOne docblock定义更改为:
/**
* @var ServiceType
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Supportal\ServiceType", fetch="LAZY", inversedBy="serverService")
* @ORM\JoinColumn(name="service_type_id", referencedColumnName="service_type_id")
*/
private $serviceType;
同时更改OneToMany,删除第@ORM\OneToMany(targetEntity="AppBundle\Entity\ServerService", fetch="EXTRA_LAZY", mappedBy="serviceType")
行
为OneToMany关系创建新字段 serverService :
/**
*
* @ORM\OneToMany(targetEntity="ServerService", mappedBy="serviceType")
*/
private $serverService;
您应加入关系字段,在本例中为 serviceType 。您定义连接的方式就像选择两个表一样。
更改为:
return $this->createQueryBuilder('ss')
->join('ss.serviceType', 't')
->where('t.serviceTypeName = :name')
->getQuery()
->execute(['name' => $name]);
由于您在此处对连接结果应用条件,因此使用LEFT JOIN或简单地JOIN是相同的。
参考文献:
How to Work with Doctrine Associations / Relations
how to do left join in doctrine
Left join ON condition AND other condition syntax in Doctrine