Symfony2 / Doctrine:如何在同一个集合中添加更多相同的实体?

时间:2015-11-02 08:18:28

标签: php entity-framework symfony doctrine-orm

我正在设计一个Symfony2应用程序,其中计算机实体与多个硬件组件相关联,即主板,CPU,磁盘,MemoryModule等。它们都由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;

例如,我在我的灯具中运行此代码:

$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' 

我如何克服这个问题?我想我应该以某种方式在连接表上添加一个索引,但我不知道它是否可能。

编辑:我也试过 - 只是为了这个缘故 - 与单向关系,同样的错误。

1 个答案:

答案 0 :(得分:3)

你无法用标准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; 
} 

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

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

这种方法的一个优点是关系可以包含额外的字段,因此您可以执行诸如保留磁盘位置的$diskBay字段之类的事情