0

我有一个像EntityA OneToMany EntityB古典建筑。实施为双向关系:如何删除没有EntityManager的集合元素#在Doctrine 2中删除(...)?

  • EntityB具有EntityA类型的属性$entityA
  • EntityA有一个属性$entityBs,包含EntityBArrayCollection元件。

现在我想删除一些EntityB元素。它的工作是这样的:

$entityManager->remove($myEntityB); 
$entityManager->flush(); 

但是我想能够只是“说” $myEntityA->removeEntityB($entityB),而不是需要关心别的。一个好处是,我可以实现一种方法EntityA#replaceEntityBs(ArrayCollection $entityBs),它只是删除所有EntityA#$entityBs并将它们替换为给定的元素。

是否有可能/如何直接从关系的逆侧除去集合的元素(当然不传递EntityManager进入实体)?

回答

0

解决方法是从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); 
     } 
    } 
}