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;