我的左连接不在Symfony4中工作

时间:2018-05-18 08:32:54

标签: symfony doctrine one-to-many many-to-one symfony4

我是Symfony的新手,我正在尝试进行基本的左连接,以根据Jobs表中的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课程中,以下函数正在尝试左连接:

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

有什么想法吗?就我的有限理解而言,注释应该形成所需的连接。

3 个答案:

答案 0 :(得分:1)

以下代码更改为我解决了这个问题。看来

  • 所需的注释是类本身的@ORM\Entity,指向存储库类
  • 对于属性,连接注释是唯一需要的(@ORM\ManyToOne

根据Preciels的评论,课堂顶部的@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();


}

答案 1 :(得分:0)

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();
}

答案 2 :(得分:0)

我没有看到任何调用来获取entityManager。

您要么忘记在getRepository()之前致电createQueryBuilder(),要么忘记在查询中添加from

避免使用可能被误认为实体名称的别名

使用双引号括起查询。因为当你碰巧写where('e.param="string"')之类的东西时会出现错误,因为DQL中的字符串不允许双引号。

$client_id更改为$client。根据教义如何处理,如果保留原样,在更新模式时,您将client_id_id作为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 Solution 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 Solution 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();
    }
}