具有一对多关系的 Symfony 连接查询

Symfony join query with One-To-Many relation

我对 symfony 和 DQL 都很陌生。我有一个查询问题,即我想比较 table 'TermAssign' 中的 'term_id' 和 table 中的 'id' 之间的 ID,然后,谁是谁匹配将在模板上呈现。 Term 和 TermAssign 之间的关系是 OneToMany。还有一个 table Offer,它与 OneToMany 和 table TermAssign 有关系。

这是我的 Term.php:

   <?php

    namespace App\OfferBundle\Entity;
    use App\OfferBundle\Repository\TermRepository;
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Collection;  
    use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=TermRepository::class)
 * @ORM\Table(name="term")
 */
class Term
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true, name="term_description")
     */
    private $term_description;

    /**
     * @ORM\OneToMany(targetEntity=TermAssign::class, mappedBy="term")
     */
    private $assign;

    public function __construct()
    {
        $this->assign = new ArrayCollection();
    }

  function getId(): ?int
    {
        return $this->id;
    }

    public function getTermDescription(): ?string
    {
        return $this->term_description;
    }

    public function setTermDescription(?string $term_description): self
    {
        $this->term_description = $term_description;

        return $this;
    }

    /**
     * @return Collection|TermAssign[]
     */
    public function getAssign(): Collection
    {
        return $this->assign;
    }

    public function addAssign(TermAssign $assign): self
    {
        if (!$this->assign->contains($assign)) {
            $this->assign[] = $assign;
            $assign->setTerm($this);
        }

        return $this;
    }

    public function removeAssign(TermAssign $assign): self
    {
        if ($this->assign->removeElement($assign)) {
            // set the owning side to null (unless already changed)
            if ($assign->getTerm() === $this) {
                $assign->setTerm(null);
            }
        }

        return $this;
    }
}

这是Offer.php:

<?php

namespace App\OfferBundle\Entity;

use App\OfferBundle\Repository\OfferRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints\DateTime;

/**
 * @ORM\Entity(repositoryClass=OfferRepository::class)
 */
class Offer
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     */
    private $title;

    /**
     * @ORM\Column(type="date", name="offer_date")
     */
    private $date;

    /**
     * @ORM\Column(type="string", unique=true)
     */
    private $number;

    /**
     * @ORM\Column(type="string")
     */
    private $description;

    /**
     * @ORM\OneToMany(targetEntity=TermAssign::class, mappedBy="offer")
     */
    private $terms;

    public function __construct()
    {
        $this->terms = new ArrayCollection();
    }

    /**
     * Getting offer's id
     */
    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * getting offer's Title
     */
    public function getTitle(): string
    {
        return $this->title;
    }

    /**
     * Setting offer's name
     */
    public function setTitle($title): self
    {
        $this->title = $title;

        return $this;
    }

    /**
     * getting offer's date
     */
    public function getDate(): ?\DateTime
    {
        return $this->date;
    }

    /**
     * Setting offer's date
     */
    public function setDate($date): self
    {
        $this->date = $date;

        return $this;
    }

    /**
     * Offer's number
     */
    public function getNumber() : string
    {
        return $this->number;
    }

    /**
     * Setting offer's number
     */
    public function setNumber($number): self
    {
        $this->number = $number;

        return $this;
    }

    /**
     * Offer's description
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Setting offer's description
     */
    public function setDescription($description): void
    {
        $this->description = $description;
    }

    /**
     * @return Collection|TermAssign[]
     */
    public function getTerms(): Collection
    {
        return $this->terms;
    }

    public function addTerm(TermAssign $term): self
    {
        if (!$this->terms->contains($term)) {
            $this->terms[] = $term;
            $term->setOffer($this);
        }

        return $this;
    }

    public function removeTerm(TermAssign $term): self
    {
        if ($this->terms->removeElement($term)) {
            // set the owning side to null (unless already changed)
            if ($term->getOffer() === $this) {
                $term->setOffer(null);
            }
        }

        return $this;
    }
}

这是TermAssign.php:

<?php

namespace App\OfferBundle\Entity;

use App\OfferBundle\Repository\TermAssignRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=TermAssignRepository::class)
 */
class TermAssign
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity=Offer::class, inversedBy="terms")
     */
    private $offer;

    /**
     * @ORM\ManyToOne(targetEntity=Term::class, inversedBy="assign")
     */
    private $term;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getOffer(): ?Offer
    {
        return $this->offer;
    }

    public function setOffer(?Offer $offer): self
    {
        $this->offer = $offer;

        return $this;
    }

    public function getTerm(): ?Term
    {
        return $this->term;
    }

    public function setTerm(?Term $term): self
    {
        $this->term = $term;

        return $this;
    }


}

我确实想出了这种查询:

 /**
 * @return Term[] Returns an array of Term objects
 */
public function findByIdField():array
{
    $em = $this->getEntityManager();
    $query = $em->createQuery("SELECT t, a FROM App\OfferBundle\Entity\Term t JOIN t.term a WHERE a.term_id = t.id");
    return $query->getResult();
}

但是没用

此外,这是我的控制器的一部分,我在其中调用要传递到模板的查询:

OfferController.php

/**
 * @Route("/{id}", name="offer_show", methods={"GET"})
 */
public function show(Offer $offer, int $id): Response
{
    $termAssigns = $this->getDoctrine()
        ->getRepository(TermAssign::class)
        ->findBy(
            ['offer'=>$id]
        );
    $terms = $this->getDoctrine()
        ->getRepository(Term::class)
        ->findByIdField();
    $conditions = $this->getDoctrine()
        ->getRepository(Condition::class)
        ->findAll();

    return $this->render('offer/show.html.twig', [
        'offer' => $offer,
        'terms'=> $terms,
        'conditions'=>$conditions,
        'termAssigns'=>$termAssigns,
    ]);
}

问题是,我该怎么做才能达到

SELECT 描述 FROM Term.t 其中 't.id'='ta.term_id'

'ta' 是 TermAssign table.

这比我想象的要简单得多...我不必创建新查询,我所要做的就是将 TermAssign 存储库导入位于 [=15 的 show() 函数=] 并使用 findBy() 函数从术语 table 中获取术语。解决方案如下:

OfferController.php:

/**
     * @Route("/{id}", name="offer_show", methods={"GET"})
     */
    public function show(Offer $offer, int $id, TermAssign $terms): Response
    {
        **$termAssigns = $this->getDoctrine()
            ->getRepository(TermAssign::class)
            ->findBy(
                ['offer'=>$id]
            );

        $terms = $this->getDoctrine()
            ->getRepository(Term::class)
            ->findBy(
                ['id'=>$terms->getId()]
            );**

        $conditions = $this->getDoctrine()
            ->getRepository(Condition::class)
            ->findAll();

        return $this->render('offer/show.html.twig', [
            'offer' => $offer,
            'terms'=> $terms,
            'conditions'=>$conditions,
            'termAssigns'=>$termAssigns,
        ]);
    }