如何删除没有EntityManager的集合元素#在Doctrine 2中删除(...)?
问题描述:
我有一个像EntityA OneToMany EntityB
古典建筑。实施为双向关系:如何删除没有EntityManager的集合元素#在Doctrine 2中删除(...)?
- 的
EntityB
具有EntityA
类型的属性$entityA
和 - 的
EntityA
有一个属性$entityBs
,包含EntityB
的ArrayCollection
元件。
现在我想删除一些EntityB
元素。它的工作是这样的:
$entityManager->remove($myEntityB);
$entityManager->flush();
但是我想能够只是“说” $myEntityA->removeEntityB($entityB)
,而不是需要关心别的。一个好处是,我可以实现一种方法EntityA#replaceEntityBs(ArrayCollection $entityBs)
,它只是删除所有EntityA#$entityBs
并将它们替换为给定的元素。
是否有可能/如何直接从关系的逆侧除去集合的元素(当然不传递EntityManager
进入实体)?
答
解决方法是从EntityB
(第一个)中删除对EntityA
的引用。在这种情况下,Doctrine将尝试在没有的情况下坚持EntityB
。但是,如果我们结合这与orphanRemoval=true
,我们将得到针对结果:
class EntityA
{
...
/**
* @var ArrayCollection
* @ORM\OneToMany(targetEntity="EntityB", mappedBy="entityA", cascade={"persist"}, orphanRemoval=true)
*/
protected $entityBs;
...
public function removeEntityB(EntityB $entityB)
{
$this->entityBs->removeElement($entityB);
$entityB->setEntityA(null);
return $this;
}
...
}
class EntityB
{
...
/**
* @var EntityA
*
* @ORM\ManyToOne(targetEntity="EntityA", inversedBy="entityBs")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="entity_a_id", referencedColumnName="id")
* })
*/
protected $entityA;
...
/**
* @param EntityA $entityA
* @return EntityB
*/
public function setEntityA(EntityA $entityA = null)
{
$this->entityA = $entityA;
return $this;
}
...
}
题外话:更换收集
因为我在这个问题指出,一个好处是,那么可以实现一个像EntityA#replaceEntityBs(ArrayCollection $entityBs)
这样的方法,我想在这里分享一个可能的实现。
第一次天真的尝试只是删除全部EntityBs
然后添加(并坚持)新的元素。
public function setEntityBs($entityBs)
{
$this->removeEntityBs();
$this->entityBs = new ArrayCollection([]);
/** @var EntityB $entityB */
foreach ($entityBs as $entityB) {
$this->addEntityB($entityB);
}
return $this;
}
public function removeEntityBs()
{
foreach ($this->getEntityBs() as $entityB) {
$this->removeEntityB($entityB);
}
return $this;
}
但如果输入集合setEntityBs(...)
包含在现有EntityBs
(即应和更新),这导致了他们的删除,只有新的元素得到了坚持。
这里是一个解决方案,即作品的希望:
public function setEntityBs($entityBs)
{
$this->removeEntityBsNotInList($entityBs);
$this->entityBs = new ArrayCollection([]);
/** @var EntityB $entityB */
foreach ($entityBs as $entityB) {
$this->addEntityB($entityB);
}
return $this;
}
private function removeEntityBsNotInList($entityBs)
{
foreach ($this->getEntityBs() as $entityB) {
if ($entityBs->indexOf($entityB) === false) {
$this->removeEntityB($entityB);
}
}
}