假设我想在Doctrine中实现以下实体:
Thing
代表任何可以对另一个Thing
执行行动的东西。 Relation
可以包含两个实体和操作的描述,其元组是唯一的。
以下是我正在尝试实现的一些示例:
正如你所看到的,订单很重要(它不像“鲍勃喜欢苹果”那样“像鲍勃这样的苹果”)。
尽管我付出了最大努力,但我找不到任何正确的方法来实现这一点。
我尝试在$relations
中创建一个名为Thing
的字段,标记为“一对多”,然后将$left
中的$right
和Relation
标记为“多对一”。问题是我不能为同一个拥有者提供两个相反的方(至少是AFAIK)。
当前实现既不允许获取Thing
字段中特定$relations
的所有关系,因为我只能指定一个反向边。
这是我到目前为止所提出的:
/** @ORM\Entity */
class Thing {
/**
* @ORM\Id
* @ORM\Column(type="integer", options={"unsigned":true})
* @ORM\GeneratedValue
*/
protected $id;
/** @ORM\Column(type="string") */
protected $name;
/**
* @ORM\OneToMany(targetEntity="Relation", mappedBy="right")
*/
protected $relations;
}
/** @ORM\Entity */
class Relation {
/** @ORM\Id @ORM\Column(type="string") */
protected $action;
/** @ORM\Id @ORM\ManyToOne(targetEntity="Thing") */
private $left;
/** @ORM\Id @ORM\ManyToOne(targetEntity="Thing", inversedBy="relations") */
private $right;
}
原来,Doctrine不直接允许这种关系。
我能想出的最好的解决方案是在Thing
中为关系而不是一个创建两个集合,然后定义一个输出两者的方法:
/** @ORM\Entity */
class Thing {
// [...]
/** @ORM\OneToMany(targetEntity="Relation", mappedBy="left") */
protected $relationsLeft;
/** @ORM\OneToMany(targetEntity="Relation", mappedBy="right") */
protected $relationsRight;
public function getRelations() {
return new ArrayCollection(array_merge(
$this->relationsLeft->toArray(),
$this->relationsRight->toArray()
));
}
}
/** @ORM\Entity */
class Relation {
// [...]
/** @ORM\Id @ORM\ManyToOne(targetEntity="Thing", inversedBy="relationsLeft") */
private $left;
/** @ORM\Id @ORM\ManyToOne(targetEntity="Thing", inversedBy="relationsRight") */
private $right;
}