Symfony2/原则:如何在同一集合中添加更多相同实体


Symfony2/Doctrine: how to add more of the same entity in the same collection?

我正在设计一个Symfony2应用程序,其中一个计算机实体与几个硬件组件相关联,即主板、CPU、磁盘、内存模块等。它们都由Doctrine中的实体表示。

我需要做的是将多个磁盘与同一台计算机关联起来,以防其硬件配置中有多个相同的磁盘。我想避免像Disk1、Disk2等多个字段,所以我在这两个实体之间设置了ManyToMany关系:

实体计算机

//... 
/**
 * @ORM'ManyToMany(targetEntity="AppBundle'Entity'Components'Disk", inversedBy="computers")
 * @ORM'JoinTable(name="computers_disks")
 */
protected $disks;

实体磁盘

//...
enter code here
/**
 * @ORM'ManyToMany(targetEntity="AppBundle'Entity'Computers'Computer", mappedBy="disks")
 */
protected $computers;

例如,我在Fixtures:中运行此代码

$testComputer = new Computer();
$cpu = $this->getReference('CPU-i3-1150');
$disk = $this->getReference('Disk-wd500blue');
//...
$testComputer->setCpu($cpu);        // OK
$testComputer->addDisk($disk);      // OK
$testComputer->addDisk($disk);      // ERROR

正如预期的那样,我得到的错误是违反完整性约束:

[PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-14'
for key 'PRIMARY' 

我该如何克服这一点?我想我应该在联接表上添加一个索引,但我不知道这是否可能。

编辑:我也尝试过——只是为了——单向关系,同样的错误。

您无法对标准ManyToMany条令关系进行尝试,因为根据定义,这些关系是唯一的,即它们只包含两个实体的唯一组合。

但您可以使用一个"关联"实体来实现这一点,该实体充当两个实体之间的中介:

class Computer { 
    /** 
     * @ORM'OneToMany(targetEntity="ComputerDisk", mappedBy="computer") 
     **/ 
    protected $computerDisks; 
} 
class ComputerDisk { 
    /** 
     * @ORM'ManyToOne(targetEntity="Computer", inversedBy="computerDisks") 
     * @ORM'JoinColumn(name="computer_id", referencedColumnName="id") 
     **/ 
    protected $computer; 
    /** 
     * @ORM'ManyToOne(targetEntity="Disk", inversedBy="computerDisks") 
     * @ORM'JoinColumn(name="disk_id", referencedColumnName="id") 
     **/ 
    protected $disk; 
} 
class Disk { 
    /** 
     * @ORM'OneToMany(targetEntity="ComputerDisk", mappedBy="disk") 
     **/ 
    protected $computerDisks; 
} 

这将类似于多对多关系,只是这个中间实体将用于保持关系,并且它不必是唯一的。

在您的情况下,此实体和磁盘之间的关系可能是单向的,因为您可能不需要知道哪些计算机持有每个磁盘,因此磁盘实体中的字段和计算机磁盘与此实体关联中的反转项可以被提交

这种方法的一个优点是,该关系可以包含额外的字段,因此您可以做一些事情,比如有一个$diskBay字段,它包含磁盘的位置