如何创建基于多个唯一键的转换后的 Doctrine 2 实体
Posted
技术标签:
【中文标题】如何创建基于多个唯一键的转换后的 Doctrine 2 实体【英文标题】:How to create a transformed Doctrine 2 entity that is based on several unique keys 【发布时间】:2016-11-08 21:52:34 【问题描述】:我尝试在 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;
RacingVehicle.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 作为主键的自己的实体(Accident),同时真正拥有自己的 PHP 类实体(我可以创建多对多关系,但在那种情况下我会赢) t 有自己的事故实体)。
【问题讨论】:
不应该RacingVehicle
也与Race
有关系吗?还是我或者它没有绑定到Race
?
【参考方案1】:
我认为您可以将Driver
和Vehicle
作为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
表中的标识符相关联,Vehicle_Id
的索引与您的标识符相关联Vehicle
表)但您可以在生命周期事件中加载或创建代理到您的 RacingVehicle
。
【讨论】:
谢谢。在尝试之后,我也最终得到了该解决方案。转换后的实体将被加载,并应用 ID(驾驶员/车辆等)查找,所以这完全没有问题。以上是关于如何创建基于多个唯一键的转换后的 Doctrine 2 实体的主要内容,如果未能解决你的问题,请参考以下文章
是否支持 Doctrine Sluggable Unique_base 选项多个字段?