我有一个实体 Room,它与自身具有 ManyToMany 关系,并且这种关系 (RoomLinkRoom) 具有属性“权重”:一个 Room 可以链接到多个 Room,具有 ordering(weight) 值(以及可能的其他属性)。
到目前为止,我的代码处理了一个或多个 RoomTo 到 RoomFrom 的链接。假设我们有: RoomA:1 RoomB:2
在 Room Form 中,我们可以将 RoomB 添加到 RoomA 我们在 RoomLinkRoom 中有这个条目:
RoomFromId:1 RoomToId:2
但这只是我需要的一半:我还需要反向部分管理。
当 RoomFromId,1 链接到 RoomToId,2 我还想添加这个中间实体:RoomFromId,2, RoomToId,1
然后我还必须管理删除部分:如果我删除房间 A,条目 (roomFrom, roomTo) : (1, 2) 将被删除,但反向 (2, 1) 也必须删除。
我怎样才能做到这一点?处理整个问题的最佳(最干净?)方法是什么?是否有处理这种情况的“标准模式”(“自动”与否)?我不确定如何进行,但可能涉及事件,例如 postFlush ?但是它是否也能够处理“反向”(To)侧的删除?
实体的(相关部分)是:
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use MyBundle\Entity\RoomLinkRoom;
/**
* Room
*
* @ORM\Table(name="room")
* @ORM\Entity(repositoryClass="MyBundle\Repository\RoomRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Room
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* @ORM\OneToMany(
* targetEntity="MyBundle\Entity\RoomLinkRoom", mappedBy="roomFrom",
* cascade={"persist", "remove"}, orphanRemoval=TRUE)
*/
private $roomFromLinks;
/**
* @ORM\OneToMany(
* targetEntity="MyBundle\Entity\RoomLinkRoom", mappedBy="roomTo",
* cascade={"persist", "remove"}, orphanRemoval=TRUE)
*/
private $roomToLinks;
public function __construct()
{
$this->roomFromLinks = new ArrayCollection();
$this->roomToLinks = new ArrayCollection();
}
public function addRoomFromLink(RoomLinkRoom $roomFromLink)
{
$this->roomFromLinks[] = $roomFromLink;
$roomFromLink->setRoomFrom($this);
return $this;
}
public function removeRoomFromLink(RoomLinkRoom $roomFromLink)
{
$this->roomFromLinks->removeElement($roomFromLink);
}
public function getRoomFromLinks()
{
return $this->roomFromLinks;
}
public function addRoomToLink(RoomLinkRoom $roomToLink)
{
$this->roomToLinks[] = $roomToLink;
$roomToLink->setRoomTo($this);
return $this;
}
public function removeRoomToLink(RoomLinkRoom $roomToLink)
{
$this->roomToLinks->removeElement($roomToLink);
}
public function getRoomToLinks()
{
return $this->roomToLinks;
}
}
和
<?php
use Doctrine\ORM\Mapping as ORM;
use MyBundle\Entity\Room;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* RoomLinkRoom.
*
* @ORM\Table(name="roomlinkroom", indexes={
* @ORM\Index(name="FK_RoomLinkRoom_roomfromId", columns={"roomfromId"}),
* @ORM\Index(name="FK_RoomLinkRoom_roomtoId", columns={"roomtoId"}),
* })
* @ORM\Entity(repositoryClass="MyBundle\Repository\RoomLinkRoomRepository")
* @UniqueEntity(
* fields={"roomFrom", "roomTo"},
* errorPath="weight",
* message="Ces salles sont déjà liées."
* )
*/
class RoomLinkRoom
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="MyBundle\Entity\Room", inversedBy="roomFromLinks")
* @ORM\JoinColumn(name="roomFromId", referencedColumnName="id", nullable=false)
*/
private $roomFrom;
/**
* @ORM\ManyToOne(targetEntity="MyBundle\Entity\Room", inversedBy="roomToLinks")
* @ORM\JoinColumn(name="roomToId", referencedColumnName="id", nullable=false)
*/
private $roomTo;
public function getId()
{
return $this->id;
}
public function setRoomFrom(Room $roomFrom)
{
$this->roomFrom = $roomFrom;
return $this;
}
public function getRoomFrom()
{
return $this->roomFrom;
}
public function setRoomTo(Room $roomTo)
{
$this->roomTo = $roomTo;
return $this;
}
public function getRoomTo()
{
return $this->roomTo;
}
}
我已经尝试在控制器中在刷新后添加:
if ($form->isSubmitted() && $form->isValid()) {
//...
$em->persist($room);
$em->flush();
//look for existing relationship between To and From
foreach ($room->getRoomFromLinks() as $rfl){
$res = $em->getRepository('MyBundle:RoomLinkRoom')
->findBy(['roomFrom' => $rfl->getRoomTo(), 'roomTo' => $room]);
//add the reverse side
if (count($res) === 0){
$rlr = new RoomLinkRoom();
$rlr->setRoomFrom($rfl->getRoomTo());
$rlr->setRoomTo($room);
$em->persist($rlr);
$em->flush();
}
}
//redirect
}
这添加了反向/补充条目,但我仍然不知道这是否干净/防错。但我敢肯定,这并不能解决删除问题。
那么有人用过这种关系吗?
我在这里看到了其他讨论(例如,这个),但是,他们似乎并不关心这种“反向”管理。
先感谢您。