1

我有一个显示电影信息的页面。我在 GET 中恢复了电影的 id。我想做的是检索每部电影的评论(我的表中有一个 filmId 列链接到电影表的主 ID)

   /**
     * @Route("/user/film/{id}", name="film")
     */
    public function film(FilmRepository $repo, CommentRepository $comRepo, EntityManagerInterface $em, Request $req, $id)
    {
        $film = $repo->find($id);

        $comments = $comRepo->findBy(array('id' => $id));





        return $this->render('film/film.html.twig', [
            'controller_name' => 'FilmController',
            'film' => $film,
            'comments' => $comments
        ]);
    }

当我做一个$comments = $comRepo->findBy(array('id' => $id)); 我收到一些评论,但基于他们的 ID 而不是电影 ID(ID 为 1 的评论将显示在 ID 为 1 的电影上,但例如 ID 为 4 的评论和电影 ID a 1 不会出现在电影 1 上,但在 id 为 4 的电影上)

我尝试通过简单地创建$comments = $comRepo->findBy(array ('filmId' => $ id));来访问filmId 字段 但我得到了错误:

执行“SELECT t0.id AS id_1, t0.content AS content_2, t0.created_at AS created_at_3, t0.author_id AS author_id_4 FROM comment t0 WHERE comment_film.film_id = ?”时发生异常 带参数 [“1”]:SQLSTATE [42S22]:找不到列:1054 'where 子句'中的未知列 'comment_film.film_id'

我在我的评论存储库中尝试了个性化请求:


public function findAllWithFilmId($filmId) 
    {
        $em = $this->getEntityManager();

        $query = $em->createQuery(
            'SELECT c
            FROM App\Entity\Comment c
            WHERE c.filmId = :filmId'
        )->setParameter('filmId', $filmId);

        return $query->getResult();
    }

但它似乎不起作用..

我该去哪里提出这样的要求? 如何从 symfony修改看似错误的请求而不破坏一切?还是有更好的方法来解决问题?

这是我的评论实体

<?php

namespace App\Entity;

use App\Entity\Film;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\CommentRepository")
 */
class Comment
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="comments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $author;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Film", inversedBy="comments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $filmId;

    /**
     * @ORM\Column(type="text")
     */
    private $content;

    /**
     * @ORM\Column(type="datetime")
     */
    private $createdAt;



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

    public function getAuthor(): ?User
    {
        return $this->author;
    }

    public function setAuthor(?User $author): self
    {
        $this->author = $author;

        return $this;
    }


    public function getFilmId(): ?Film
    {
        return $this->filmId;
    }

    public function setFilmId(?Film $filmId): self 
    {
        $this->filmId = $filmId;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeInterface
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}

我认为错误可能来自注释,因为在 make: entity 期间从 symfony 开始,我定义了稍后在 phpmyadmin 中更正的类型关系,但不是代码。比如我们可以看到filmId在ManyToMany中,但我认为应该在OneToOne中(FilmId只能有一个id,一个id只能对应一个filmId),但我怕我改了某些东西就坏了一切

4

2 回答 2

2

如果您正确设置了 ORM 关系,它应该很简单:

$film = $repo->find($id);
$comments = $film->getComments();

您可能缺少 Film.php 中的映射。

这是一个 XML 示例,应该很容易转换为注释:

电影中:

<one-to-many field="comments" target-entity="App\...\Comments" mapped-by="film"/>

在评论中:

<many-to-one field="film" target-entity="App\...\Film" inversed-by="comments"/>
于 2020-03-25T15:16:50.177 回答
0

首先,我建议您阅读有关实体之间关系的更多信息。

因为,目前的注释说你可以对很多电影有很多评论。这是不对的。一条评论可能属于一部电影。一部电影可以有很多评论。

另外,我想指出,据我所知,@JoinColumn 应该位于子实体中,即包含指向 FK 的链接的位置。因此,您的实体应如下所示:

评论:

<?php

namespace App\Entity;

use App\Entity\Film;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\CommentRepository")
 */
class Comment
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="comments")
     */
    private $author;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Film", inversedBy="comments")
     * Here we set property for our table and property of foreign table to map our comment to the right film
     * nullable, because comment couldn't be without film 
     * @ORM\JoinColumn(name="film_id", referencedColumnName="id", nullable=false)
     */
    private $film;

    /**
     * @ORM\Column(type="text")
     */
    private $content;

    /**
     * @ORM\Column(type="datetime")
     */
    private $createdAt;


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

    public function getAuthor(): ?User
    {
        return $this->author;
    }

    public function setAuthor(?User $author): self
    {
        $this->author = $author;

        return $this;
    }


    public function getFilmId(): ?Film
    {
        return $this->filmId;
    }

    public function setFilmId(?Film $filmId): self
    {
        $this->filmId = $filmId;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getCreatedAt(): ?DateTimeInterface
    {
        return $this->createdAt;
    }

    public function setCreatedAt(DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}

电影:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\FilmRepository")
 */
class Film
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Comment", mappedBy="film")
     */
    private $comments;

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

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

    public function setId($id)
    {
        $this->id = $id;
        return $this;
    }

    public function getComments(): Collection
    {
        return $this->comments;
    }

    public function setComments(Collection $comments): Film
    {
        $this->comments = $comments;
        return $this;
    }
}

因此,现在,您可以通过以下方式检索您的评论:

/**
     * @Route("/user/film/{id}", name="film")
     */
    public function film($id)
    {
        /** @var null|EntityManager $entityManager */
        $entityManager = $this->get('doctrine.orm.entity_manager');
        if (null == ($film = $entityManager->getRepository(Film::class)->find($id))){
            throw new NotFoundHttpException('Film not found');
        }

        $comments = $film->getComments();

        return $this->render('film/film.html.twig', [
            'film' => $film,
            'comments' => $comments
        ]);
    }
于 2020-03-27T15:31:23.283 回答