0

나는 EntityA OneToMany EntityB과 같은 고전적인 구조를 가지고있다. 양방향 관계로서 구현 :Doctrine 2에서 EntityManager # remove (...)없이 콜렉션 요소를 제거하는 방법은 무엇입니까?

  • EntityBArrayCollectionEntityB의 요소를 포함하는 유형의 속성 EntityA$entityA
  • EntityA$entityBs 특성을 갖고있다.

이제 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); 
     } 
    } 
} 
: 여기

는 바란 작동하는 솔루션입니다