【问题标题】:My left join is not working in Symfony4 [duplicate]我的左连接在 Symfony4 中不起作用 [重复]
【发布时间】:2018-05-18 08:32:54
【问题描述】:

我是 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

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

【问题讨论】:

  • @k0pernikus 是的。解决问题后,它似乎与以下内容重复:https://stackoverflow.com/questions/6899335/doctrine-class-has-no-association-named您如何将其标记为这样?
  • 您可以投票关闭它并将其标记为重复。然后由社区决定关闭或保持开放。作为 OP,您可以选择接受以“是的,这解决了我的问题”的投票结束,并且它将优先于社区投票。
  • 太棒了。都整理好了。谢谢你:)
  • 不客气 :)

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


【解决方案1】:

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

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

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

使用双引号将您的查询括起来。因为当您碰巧写where('e.param="string"') 之类的内容时,您会遇到错误,因为 DQL 中的字符串不允许使用双引号。

$client_id 更改为$client。按照教义如何做事,如果保持原样,您将在更新架构时拥有client_id_idas 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();
    }
}

【讨论】:

  • @Liam 更新了我的答案,你有一些错误,应该像我一样工作......不要忘记更新架构......;)
  • 啊!我的 JobsRepository 类已经在扩展 Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository 如果我将其切换出来,这可能会导致问题吗?
  • @Liam Doctrine 应该可以很好地处理 id ......至于你的扩展,我不确定如何处理它。我从来没有扩展我的存储库,它可能是 Symfony4 特有的(我使用 3.4 作为 LTS)。无论如何,它应该已经帮助你纠正了一些部分...... ;)
  • 能否更新您的问题中的代码?! (添加说明您已更新的注释)
  • (排名不够高,无法开始聊天..)我已经更新了我的答案。现在一切似乎都在工作。注释设置错误有几个问题。检查下面的my answer。感谢您的帮助!
【解决方案2】:

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

  • 所需的注释是类本身上的@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();


}

【讨论】:

  • 哦...您没有设置实体注释...没有注意到这一点,因为它不在您的代码示例中...您不生成带有教义的实体吗?它应该默认添加它们
  • 以前没有。由于我遵循在线指南,我现在使用 CLI 工具:)
【解决方案3】:
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();
}

【讨论】:

  • 这也不起作用。相同的错误,但别名不同。 [语义错误] 第 0 行,“my_client”附近的第 71 列:错误:App\Entity\Jobs 类没有名为 client_id 的关联。问题似乎出在关联本身,而不是查询。
  • imanali,为什么要添加一个结构来将jobs 更改为数组?它甚至没有在代码示例中指定...此外,您没有为关系定义类型和生成的值...
猜你喜欢
  • 2015-12-02
  • 1970-01-01
  • 2012-09-10
  • 2019-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多