如何创建基于多个唯一键的转换后的 Doctrine 2 实体

How to create a transformed Doctrine 2 entity that is based on several unique keys

我尝试在 Doctrine 2 的场景中实现以下内容:

这在 Skipper 中类似于以下内容:

导出到基于 Doctrine 2 注释的实体后,这看起来像这样(Getter 和 setter 被剪掉):

Driver.php

<?php
namespace Racing\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Driver
{
    /**
     * @ORM\Id
     * @ORM\Column(type="bigint")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $Id;

    /**
     * @ORM\Column(type="text", nullable=false)
     */
    private $Name;
}

Vehicle.php

<?php
namespace Racing\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Vehicle
{
    /**
     * @ORM\Id
     * @ORM\Column(type="bigint")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $Id;

    /**
     * @ORM\Column(type="text", nullable=false)
     */
    private $Name;
}

Race.php

<?php
namespace Racing\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Race
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $Id;

    /**
     * @ORM\Column(type="text", nullable=false)
     */
    private $Name;
}

Accident.php

<?php
namespace Racing\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Accident
{
    /**
     * @ORM\Column(type="text", nullable=false)
     */
    private $Description;

    /**
     * @ORM\ManyToOne(targetEntity="Racing\Entity\RacingVehicle")
     * @ORM\JoinColumns({
     *     @ORM\JoinColumn(name="Racing_Vehicle_Driver_Id", referencedColumnName="Driver_Id", nullable=false),
     *     @ORM\JoinColumn(name="Racing_Vehicle_Vehicle_Id", referencedColumnName="Vehicle_Id", nullable=false)
     * })
     */
    private $RacingVehicle;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Racing\Entity\Race")
     * @ORM\JoinColumn(name="Race_Id", referencedColumnName="Id", nullable=false)
     */
    private $Race;
}

赛车Vehicle.php

<?php
namespace Racing\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class RacingVehicle
{
    /**
     * @ORM\Column(type="integer", nullable=false)
     */
    private $Startnumber;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Racing\Entity\Driver")
     * @ORM\JoinColumn(name="Driver_Id", referencedColumnName="Id", nullable=false)
     */
    private $Driver;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Racing\Entity\Vehicle")
     * @ORM\JoinColumn(name="Vehicle_Id", referencedColumnName="Id", nullable=false)
     */
    private $Vehicle;
}

测试样本如下所示:

// Get the entity manager
$sservicelocator = $this->getServiceLocator();
$entitymanager = $sservicelocator->get('doctrine.entitymanager.orm_default');

// Create a driver
$driver = new Driver();
$driver->setName("Michael Schumacher");
$entitymanager->persist($driver);

// Create a vehicle
$vehicle = new Vehicle();
$vehicle->setName("Ferrari");
$entitymanager->persist($vehicle);

// Create a race
$race = new Race();
$race->setName("Monaco");
$entitymanager->persist($race);

// Create a racing vehicle
$racingvehicle = new RacingVehicle();
$racingvehicle->setDriver($driver);
$racingvehicle->setVehicle($vehicle);
$racingvehicle->setStartnumber(42);
$entitymanager->persist($racingvehicle);

// Create an accident
$accident = new Accident();
$accident->setRace($race);
$accident->setRacingVehicle($racingvehicle);
$entitymanager->persist($accident); // <-------------- Error line

// Flush
$entitymanager->flush();

一旦我尝试坚持事故,我得到这个错误:

The given entity of type 'Racing\Entity\Accident' (Racing\Entity\Accident@0000000072a5fbd400007f1c433b761e) has no identity/no id values set. It cannot be added to the identity map.

所以我的问题是:如何创建一个自己的实体(事故),它以 RacingVehicle 和 Race 作为主键,同时真正拥有一个自己的 PHP class 实体(我可以创建很多到很多关系,但在那种情况下我不会有自己的事故实体)。

我认为您可以将 DriverVehicle 作为 ID 添加到 RacingVehicle。然后 Accident 看起来像这样:

<?php
namespace Racing\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Accident
{
    //...

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Racing\Entity\Driver")
     * @ORM\JoinColumn(name="Driver_Id", referencedColumnName="Id", nullable=false)
     */
    private $Driver;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Racing\Entity\Vehicle")
     * @ORM\JoinColumn(name="Vehicle_Id", referencedColumnName="Id", nullable=false)
     */
    private $Vehicle;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Racing\Entity\Race")
     * @ORM\JoinColumn(name="Race_Id", referencedColumnName="Id", nullable=false)
     */
    private $Race;

    //...
}

这意味着你得到了一个三列的组合键。您现在可以使用 Driver_Id 栏和 Vehicle_Id 栏来解决事故中的 RacingVehicle

不确定是否可以直接映射它,因为它可能会导致索引冲突(因为 Driver_Id 的索引与 Driver table 中的标识符相关联Vehicle_Id 的索引到 Vehicle table 中的标识符)但是您可以例如在生命周期事件中加载或创建 RacingVehicle 的代理。