实体学说之间的关系。如何引用“外键”?

时间:2018-11-26 14:10:45

标签: postgresql symfony doctrine

我目前正在使用 Symfony Doctrine ,并且在引用两个实体时遇到了一些麻烦。

我有一个名为cinema的实体和另一个名为theater的实体。这是OneToMany的关系,一个电影院可以拥有许多剧院。

我在cinema_id中创建了一个theater,以便可以关联电影院和剧院。

我已经创建了一个控制器,以使用API​​中的数据并将数据存储到Postgres数据库中。这是控制器:

TheaterController

namespace App\Controller;

use GuzzleHttp\Client;
use App\Entity\Cinema;
use App\Entity\Theater;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class TheaterController extends AbstractController
{
/**
 * @Route("/theater", name="theater")
*/
public function Theater(Request $request)
{   
    $client = new Client();

    $res = $client->request('GET','api-content');

    $arrayContent = json_decode($res->getBody());

    foreach ($arrayContent as $value)
    {
        $entityManager = $this->getDoctrine()->getManager();

        $theater_cinema_id = $entityManager->getReference(Cinema::Cinema, $id);
        $theater->addId($theater_cinema_id);
        $theater_booking_cinema = 'value';
        $theater_booking_id = $value->id;

        $theater = new theater();
        $theater->setId($theater_cinema_id);
        $theater->setBookingCinema($theater_booking_cinema);
        $theater->setBookingId($theater_booking_id);
        //echo $theater;

        $entityManager->persist($theater);
        $entityManager->flush();
    }
  }
}

我的问题是,如何引用id中的cinemacinema_id中的theater?我在做什么错了?

这两个实体是:

Cinema

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass="App\Repository\CinemaRepository")
*/

class Cinema
{

/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

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

/**
 * @ORM\Column(type="integer")
 */
private $is_active;

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

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

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

public function getName(): ?string
{
    return $this->name;
}

public function setName(string $name): self
{
    $this->name = $name;

    return $this;
}

public function getIsActive(): ?int
{
    return $this->is_active;
}

public function setIsActive(int $is_active): self
{
    $this->is_active = $is_active;

    return $this;
}

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

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

    return $this;
}

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

public function setUpdatedAt(\DateTimeInterface $updated_at): self
{
    $this->updated_at = $updated_at;

    return $this;
}
}

Theater

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass="App\Repository\TheaterRepository")
*/

class Theater
{

/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Cinema")
 * @ORM\JoinColumn(nullable=false)
 */
private $cinema;

/**
 * @ORM\Column(type="string", length=255)
 */
private $booking_cinema;

/**
 * @ORM\Column(type="integer")
 */
private $booking_id;

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

public function getCinema(): ?cinema
{
    return $this->cinema;
}

public function setCinema(?cinema $cinema): self
{
    $this->cinema = $cinema;

    return $this;
}

public function getBookingCinema(): ?string
{
    return $this->booking_cinema;
}

public function setBookingCinema(string $booking_cinema): self
{
    $this->booking_cinema = $booking_cinema;

    return $this;
}

public function getBookingId(): ?int
{
    return $this->booking_id;
}

public function setBookingId(int $booking_id): self
{
    $this->booking_id = $booking_id;

    return $this;
}
}

2 个答案:

答案 0 :(得分:0)

Doctrine是一个ORM,这意味着您不必考虑表,而可以考虑实体。您不用考虑外键,而要考虑实体之间的关系。

您的API正在为您提供电影院ID,或者您可以通过其他方式访问它?您可以使用以下方法检索电影院:

$cinema = $entityManager->getRepository('App:Cinema')->findOneById($cinema_id);

您想告诉我们剧院属于哪个电影院?使用这个:

$theater->setCinema($cinema); 

Doctrine本身将构建并执行查询以获取所需的数据。

答案 1 :(得分:0)

据我了解,您在一个剧院里有很多电影院。因此,您已将以下代码添加到Theater实体中:

// ...

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

// ...

/**
 * @var ArrayCollection $cinemas
 * @ORM\OneToMany(targetEntity="App\Entity\Theater", mappedBy="theater")
 */
public $cinemas;

// ...

/**
 * Theater constructor.
 */
public function __construct()
{
    $this->cinemas = new ArrayCollection();
}

// ...

/**
 * @return array
 */
public function getCinemas(): array
{
    return $this->cinemas->toArray()
}

/**
 * @return Theater
 */
public function addCinema(Cinema $cinema): self
{
    $this->cinemas->add($cinema);

    return $this;
}

// ...

然后将以下代码传递到您的Cinema实体:

// ...

use Doctrine\ORM\Mapping as ORM;

// ...

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Theater", inversedBy="cinemas")
 * @ORM\JoinColumn(name="theater_id", referencedColumnName="id", nullable=FALSE)
 */
 private $theater;

// ...

然后,您可以从cinemas实体访问Theater实体:

$theaterRepository = $this->getDoctrine()->getManager()->getRepository(Theater::class);
$theater = $theaterRepository->findBy(['id' => 1]);
$cinemas = $theater->getCinemas(); // array

/** @var Cinema $cinema */
foreach($cinemas as $cinema) {
    // ...
}

或将新的Cinema添加到您的Theater

$theaterRepository = $this->getDoctrine()->getManager()->getRepository(Theater::class);
$theater = $theaterRepository->findBy(['id' => 1]);

$cinema = new Cinema();
// ...
$theater->addCinema($cinema)
// Persist, flush, e.t.c

关于ArrayCollection,您可以阅读here

您可以从任何Theater实体访问Cinema实体:

$cinemaRepository = $this->getDoctrine()->getManager()->getRepository(Cinema::class);
$cinema = $cinemaRepository->findBy(['id' => 1]);
$theater = $cinema->getTheater(); // Theater object

或将Theater添加到您的Cinema

$cinema = new Cinema();
$theater = new Theater();
// ...
$cinema->setTheater($theater);
// ...
// Persist, flush, e.t.c