我的左连接在 Symfony4 中不起作用
My left join is not working in Symfony4
我是 Symfony 的新手,我正在尝试进行基本的左连接以根据工作 table 中的 client_id 拉入客户名称。
App\Entity\Jobs
:
class Jobs
{
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="App\Entity\Clients", inversedBy="jobs")
* @ORM\JoinColumn(nullable=false)
*/
private $client;
应该加入 App\Entity\Clients
:
class Clients
{
/**
* @ORM\Column(type="integer")
* @ORM\OneToMany(targetEntity="App\Entity\Jobs", mappedBy="client")
*/
private $jobs;
在我的 App\Repository\JobsRepository
class 中,以下函数正在尝试左连接:
use App\Entity\Jobs;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
class JobsRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Jobs::class);
}
public function allWithClientName()
{
return $this->createQueryBuilder('job')
->leftJoin('job.client_id', 'client')
->getQuery()
->execute();
}
}
返回的错误是:
[Semantical Error] line 0, col 60 near 'client': Error: Class App\Entity\Jobs has no association named client_id
有什么想法吗?就我有限的理解而言,注释应该形成所需的连接。
use Doctrine\Common\Collections\ArrayCollection;
////////////////////////////////////////////////////
class Clients
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @ORM\OneToMany(targetEntity="App\Entity\Jobs", mappedBy="client_id")
*/
private $jobs; // Here change your $id -> to $jobs
public function __construct()
{
$this->jobs = new ArrayCollection();
}
在您的存储库中:
public function allWithClientName()
{
return $this->createQueryBuilder('job')
->leftJoin('job.client_id', 'my_client')
->addSelect('my_client')
->getQuery()
->execute();
}
我没有看到任何获取 entityManager 的调用。
您要么忘记在 createQueryBuilder()
之前调用 getRepository()
,要么忘记在查询中添加 from
。
避免使用可能被误认为实体名称的别名
使用双引号将您的查询括起来。因为当您碰巧写 where('e.param="string"')
之类的东西时会出错,因为 DQL 中的字符串不允许使用双引号。
将 $client_id
更改为 $client
。按照学说如何做事,如果保持原样,您将在更新架构时拥有 client_id_id
as SQL 列。
避免复数实体...Donctrine 不喜欢它们...;)
这里是完整的代码更正
工作
class Jobs {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Clients", inversedBy="id")
* @ORM\JoinColumn(nullable=false)
*/
private $client;
}
客户端
class Clients {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
*@ORM\OneToMany(targetEntity="App\Entity\Jobs", mappedBy="client")
*/
private $jobs
}
JobsRepository 解决方案 1
use App\Entity\Jobs
class JobsRepository extends \Doctrine\ORM\EntityRepository {
public function repoQuery() {
$em=$this->getEntityManager();
return $em->getRepository(Jobs::class)
->createQueryBuilder("j")
->leftJoin("j.client", "c")
->getQuery()
->execute();
}
}
JobsRepository 解决方案 2
use App\Entity\Jobs
class JobsRepository extends \Doctrine\ORM\EntityRepository {
public function repoQuery() {
$em=$this->getEntityManager();
return $em->createQueryBuilder()
->from(Jobs::class, "j")
->leftJoin("j.client", "c")
->getQuery()
->execute();
}
}
下面的代码更改为我解决了这个问题。看来
- 所需的注释是 class 本身的
@ORM\Entity
,指向存储库 class
- 对于 属性 连接注释是唯一需要的 (
@ORM\ManyToOne
)
根据 Preciels 的评论,class 顶部的 @ORM\Entity(repositoryClass=?)
注释非常重要。
工作代码
App\Entity\Jobs
:
/**
* @ORM\Entity(repositoryClass="App\Repository\JobsRepository")
*/
class Jobs
{
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Clients", inversedBy="client")
*/
private $client;
App\Entity\Clients
:
/**
* @ORM\Entity(repositoryClass="App\Repository\ClientsRepository")
*/
class Clients
{
/**
* @ORM\OneToMany(targetEntity="App\Entity\Jobs", mappedBy="client", cascade={"persist", "remove"})
*/
private $client;
App\Repository\JobsRepository
:
/**
* @return array
*/
public function allWithClientName() {
return $this->createQueryBuilder('j')
->select('j as job', 'c.name as client')
->leftJoin('j.client', 'c')
->getQuery()
->execute();
}
我是 Symfony 的新手,我正在尝试进行基本的左连接以根据工作 table 中的 client_id 拉入客户名称。
App\Entity\Jobs
:
class Jobs
{
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="App\Entity\Clients", inversedBy="jobs")
* @ORM\JoinColumn(nullable=false)
*/
private $client;
应该加入 App\Entity\Clients
:
class Clients
{
/**
* @ORM\Column(type="integer")
* @ORM\OneToMany(targetEntity="App\Entity\Jobs", mappedBy="client")
*/
private $jobs;
在我的 App\Repository\JobsRepository
class 中,以下函数正在尝试左连接:
use App\Entity\Jobs;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
class JobsRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Jobs::class);
}
public function allWithClientName()
{
return $this->createQueryBuilder('job')
->leftJoin('job.client_id', 'client')
->getQuery()
->execute();
}
}
返回的错误是:
[Semantical Error] line 0, col 60 near 'client': Error: Class App\Entity\Jobs has no association named client_id
有什么想法吗?就我有限的理解而言,注释应该形成所需的连接。
use Doctrine\Common\Collections\ArrayCollection;
////////////////////////////////////////////////////
class Clients
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @ORM\OneToMany(targetEntity="App\Entity\Jobs", mappedBy="client_id")
*/
private $jobs; // Here change your $id -> to $jobs
public function __construct()
{
$this->jobs = new ArrayCollection();
}
在您的存储库中:
public function allWithClientName()
{
return $this->createQueryBuilder('job')
->leftJoin('job.client_id', 'my_client')
->addSelect('my_client')
->getQuery()
->execute();
}
我没有看到任何获取 entityManager 的调用。
您要么忘记在 createQueryBuilder()
之前调用 getRepository()
,要么忘记在查询中添加 from
。
避免使用可能被误认为实体名称的别名
使用双引号将您的查询括起来。因为当您碰巧写 where('e.param="string"')
之类的东西时会出错,因为 DQL 中的字符串不允许使用双引号。
将 $client_id
更改为 $client
。按照学说如何做事,如果保持原样,您将在更新架构时拥有 client_id_id
as SQL 列。
避免复数实体...Donctrine 不喜欢它们...;)
这里是完整的代码更正
工作
class Jobs {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Clients", inversedBy="id")
* @ORM\JoinColumn(nullable=false)
*/
private $client;
}
客户端
class Clients {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
*@ORM\OneToMany(targetEntity="App\Entity\Jobs", mappedBy="client")
*/
private $jobs
}
JobsRepository 解决方案 1
use App\Entity\Jobs
class JobsRepository extends \Doctrine\ORM\EntityRepository {
public function repoQuery() {
$em=$this->getEntityManager();
return $em->getRepository(Jobs::class)
->createQueryBuilder("j")
->leftJoin("j.client", "c")
->getQuery()
->execute();
}
}
JobsRepository 解决方案 2
use App\Entity\Jobs
class JobsRepository extends \Doctrine\ORM\EntityRepository {
public function repoQuery() {
$em=$this->getEntityManager();
return $em->createQueryBuilder()
->from(Jobs::class, "j")
->leftJoin("j.client", "c")
->getQuery()
->execute();
}
}
下面的代码更改为我解决了这个问题。看来
- 所需的注释是 class 本身的
@ORM\Entity
,指向存储库 class - 对于 属性 连接注释是唯一需要的 (
@ORM\ManyToOne
)
根据 Preciels 的评论,class 顶部的 @ORM\Entity(repositoryClass=?)
注释非常重要。
工作代码
App\Entity\Jobs
:
/**
* @ORM\Entity(repositoryClass="App\Repository\JobsRepository")
*/
class Jobs
{
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Clients", inversedBy="client")
*/
private $client;
App\Entity\Clients
:
/**
* @ORM\Entity(repositoryClass="App\Repository\ClientsRepository")
*/
class Clients
{
/**
* @ORM\OneToMany(targetEntity="App\Entity\Jobs", mappedBy="client", cascade={"persist", "remove"})
*/
private $client;
App\Repository\JobsRepository
:
/**
* @return array
*/
public function allWithClientName() {
return $this->createQueryBuilder('j')
->select('j as job', 'c.name as client')
->leftJoin('j.client', 'c')
->getQuery()
->execute();
}