2015-11-02 103 views
2

我正在设计一个Symfony2应用程序,其中一个计算机实体与几个硬件组件,即主板,CPU,磁盘,MemoryModule等等相关联。他们都是在学说中由实体代表的。Symfony2/Doctrine:如何在同一个集合中添加更多相同的实体?

如果在硬件配置中有多个相同的磁盘,我需要做的是将多个磁盘关联到同一台计算机。我想,以避免像磁盘1,磁盘2等多个领域,所以我设置了两个实体之间的多对多关系:

实体计算机

//... 

/** 
* @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' 

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

编辑:我也试过 - 只是为了 - 与单向关系,相同的错误。

回答

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场,其保持的盘

+0

非常感谢卡洛斯的位置,其实我在另一个问题上听说过一个“乔伊班”。这非常有帮助。 我也想管理它在一个奏鸣曲管理形式,即有一个“添加磁盘”按钮,但我想这不是微不足道的。 如果我为此打开另一个问题,可能会更好吗?你有什么经验吗? – godzillante

+1

首先尝试实现它,如果你没有得到它的工作,打开一个不同的问题 –

相关问题