Doctrine 条令2具有三个实体和一个联接表的多对多

Doctrine 条令2具有三个实体和一个联接表的多对多,doctrine,many-to-many,doctrine-orm,Doctrine,Many To Many,Doctrine Orm,我有三张桌子 People - id -pk - name Roles - id -pk - roleName Events - id -pk - title 和一个联接表 event_performers - event_id -pk - role_id -pk - people_id -pk 一个事件有许多角色。 角色由一个人执行。 角色与许多事件关联。 一个人可以扮演许多角色 所以我希望,当我得到一个事件时,我可以访问一组与该事件相关的角色,从这些角色中我可以得到

我有三张桌子

People
 - id -pk
 - name

Roles
 - id -pk
 - roleName

Events
 - id -pk
 - title
和一个联接表

event_performers
 - event_id -pk
 - role_id -pk
 - people_id -pk
一个事件有许多角色。 角色由一个人执行。 角色与许多事件关联。 一个人可以扮演许多角色

所以我希望,当我得到一个事件时,我可以访问一组与该事件相关的角色,从这些角色中我可以得到执行该角色的人


我不确定我将如何在条令2中映射这一点?

大约一周前,我遇到了同样的问题。我向信条IRC频道的用户咨询了最佳解决方案(或者至少是最常用的解决方案)。这是如何做到的:

创建一个名为EventsPeopleRoles的新实体,并使用@manytone、$event、$person和$role映射三个属性

每个关联的映射应类似于此:

/**
 * @ManyToOne(targetEntity="Events", inversedBy="eventsPeopleRoles")
 * @JoinColumn(name="event_id", referencedColumnName="id", nullable=false)
 */
private $event;
然后,在三个相关实体中的每一个中,对关联的反面进行如下编码:

/**
 * @OneToMany(targetEntity="EventsPeopleRoles", mappedBy="event")
 */
private $eventsPeopleRoles;
然后,您可以选择向“联接实体”添加$id属性,或者使用所述的复合主键,并在实体类定义中添加唯一的约束注释。请注意,复合外键仅从原则2.1开始受支持


我对这个解决方案持怀疑态度,因为我不喜欢只为连接目的创建实体的想法。这看起来像是作弊,或者至少与ORM设计原则相反。但我相信这是理论专家公认的解决方案(至少目前是如此)。

@cantera25的解决方案是正确的

我想补充一点

通常,如果您的连接实体将两个以上的实体连接在一起,这表明它在您的信息体系结构中具有相当重要的作用,应该重命名

例如,我正在为马厩开发的应用程序有一个
Booking
实体

每个
预订
至少有一名
骑手
为该预订骑一匹

我最初设计了一个名为
BookingRiderHorse
的实体,将这三者连接在一起

不用说,当我稍后再次访问代码时,这将是非常混乱和难以理解的

我将以前的
预订
实体重命名为
骑行
,并将
预订骑行
实体重命名为
预订

现在在业务逻辑中,创建了
预订
,并且必须具有现有的
骑乘
骑手
记录。每个
预订
只有一匹
骑手
,但每个
骑乘
可以有许多
预订


这与使用具有有趣名称的联接表相同,但更容易理解,这意味着我可以处理业务逻辑,而无需考虑联接是如何工作的。

如果有人像我一样是新手,我将在@cantera的这一伟大答案中添加一些注释:

在这三个实体中,您必须添加他建议的代码,只需注意在“manytone”和“JoinColumn”之前必须包含“ORM\”。我还添加了“@var”注释,以尽可能地澄清:

在Entity name=“eventsPeopleRoles”中,添加三个实体中每个实体的引用:

/**
 * @var Events $event
 *
 * @ORM\ManyToOne(targetEntity="Events", inversedBy="eventsPeopleRoles")
 * @ORM\JoinColumn(name="event_id", referencedColumnName="id", nullable=false)
 */
private $event;

/**
 * @var Events $people
 *
 * @ORM\ManyToOne(targetEntity="Person", inversedBy="eventsPeopleRoles")
 * @ORM\JoinColumn(name="person_id", referencedColumnName="id", nullable=false)
 */
private $people;

/**
 * @var Role $role
 *
 * @ORM\ManyToOne(targetEntity="Role", inversedBy="eventsPeopleRoles")
 * @ORM\JoinColumn(name="role_id", referencedColumnName="id", nullable=false)
 */
private $role;
在您的实体名称=“事件”中

在您的实体名称=“个人”中

在您的实体名称=“角色”中


谢谢你的回复,我会尝试一下,让你知道我是如何进步的。这对我来说似乎也很好用。。。谢谢分享!您在EventsOpperoles实体类中犯了一个错误。而不是私人活动;最后,它是私有的$角色;谢谢埃德加,我修正了我的答案。
/**
 * @var ArrayCollection $eventsPeopleRoles
 *
 * @ORM\OneToMany(targetEntity="EventsPeopleRoles", mappedBy="event")
 */
private $eventsPeopleRoles;
/**
 * @var ArrayCollection $eventsPeopleRoles
 *
 * @ORM\OneToMany(targetEntity="EventsPeopleRoles", mappedBy="people")
 */
private $eventsPeopleRoles;
/**
 * @var ArrayCollection $eventsPeopleRoles
 *
 * @ORM\OneToMany(targetEntity="EventsPeopleRoles", mappedBy="roles")
 */
private $eventsPeopleRoles;