Php Symfony4-如何更新条令阵列集合?

Php Symfony4-如何更新条令阵列集合?,php,symfony,doctrine,arraycollection,Php,Symfony,Doctrine,Arraycollection,我的实体中有一个成员是arrayCollection。使用经典的表单生成器可以很好地工作,我可以选择多个项目并将其持久化。但是,当我尝试更新控制器中的对象时,会出现错误:“调用数组上的成员函数setFaavailability() 本人实体的简历: /** * @ORM\ManyToOne(targetEntity="App\Entity\FaAvailability", inversedBy="faavailability") * @ORM\JoinColumn(nullable=

我的实体中有一个成员是arrayCollection。使用经典的表单生成器可以很好地工作,我可以选择多个项目并将其持久化。但是,当我尝试更新控制器中的对象时,会出现错误:“调用数组上的成员函数setFaavailability()

本人实体的简历:

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\FaAvailability", 
   inversedBy="faavailability")
 * @ORM\JoinColumn(nullable=true)
 * @ORM\Column(type="array")
 */
 public $faavailability;

 /**
 * @return mixed
 */
public function getFaavailability()
{
    return $this->faavailability;
}

/**
 * @param mixed $faavailability
 */
public function setFaavailability($faavailability)
{
    $this->faavailability = $faavailability;
}
在我的控制器中:

 $varFaavailability = $animal->faperson->getFaavailability();
 foreach($varFaavailability as $availability){
         if($availability->getName() == $animal->typepet->getName()){
           $varFaavailability->removeElement($availability);
           $faPerson = $em->getRepository(FaPerson::class) >findById($animal->faperson->getId());
           $faPerson->setFaavailability($varFaavailability);
           $em->persist($faPerson);
           $em->flush();
         }
}

有什么想法吗

如果我记得很清楚的话,当您将字段设置为ArrayCollection时,这意味着您在两个实体之间具有一对一的关系。 从您的代码中,我可以告诉您,您试图将数据持久化到错误的实体中。您通常在每个项目(1-to-N)中添加拥有的实体id(1-to-N)并将其持久化。在代码中,您试图同时设置所有引用,这是永远不会发生的。删除setFaavailability()或重新定义实体的关系


决不能在一个
super-duper
setter函数中批量添加外键关系。循环浏览所有项目并设置对“父”实体的引用。

问题在这部分:
$faPerson=$em->getRepository(faPerson::class)->findById($animal->faPerson->getId())

findBy*
方法将尝试查找多个实体并在
集合中返回它们。
如果您正在寻找一个人,可以使用
findOneById
。或者(假设
id
配置为条令中的标识符),您甚至可以使用
find
方法:
$faPerson=$em->getRepository(faPerson::class)->find($animal->faPerson->getId())

一些一般性意见:

  • 在理论上,你永远不必使用ID。使用实体 物体!例如,如果从请求参数获取ID,则只需要findById
  • 您应该重新考虑变量的命名,以明确它是集合($availabilities)还是单个($availabilities)
  • 始终使用getter/setter方法而不是字段(typepet vs getTypepet())
  • 最后调用flush()one以更新单个事务中的所有实体
  • 根据我的理解,我已经重命名了下面的变量。但是,我仍然不确定$animal->faperson->getFaavailabilities()返回的是什么,因为在开始时,您希望遍历结果,然后通过setFaavailability()将其设置为单个结果


    尝试从$faavailability.ManyToOne关系的注释中删除“@ORM\Column(type=“array”)”,不会返回arrayCollection,仅返回manytomy或onetomany。对于您的解决方案,我没有错误,但不会持久化任何内容。您知道为什么吗?您可能需要设置级联,以便在持久化人员时也保持可用性。您可以使用“持久化”级联实现这一点:是的,您是对的,这段代码更好。当if条件为true时,我只想从arrayCollection中删除一个元素。如果我执行$faPerson->setFaavailability($varFaavailability),Faavailability proprety上没有任何持久性。我更改为$faPerson->setFaavailability($varFaavailability->removeElement($availability)),它将保留值“1”。。。这很奇怪。你有什么想法吗?只需调用$varFaavailability->removelement($availability);没有setFaavailability()
     //Should be a Doctrine ArrayCollection
     $varFaavailabilities = $animal->faperson->getFaavailabilities();
    
     foreach($varFaavailability as $availability){
             if($availability->getName() == $animal->getTypepet()->getName()) {
    
               //Why do you want to remove an element from the current loop?
               $varFaavailability->removeElement($availability);
    
               //No need to use Id
               $faPerson = $animal->getFaperson();
    
               //A single one?
               $faPerson->setFaavailability($availability);
    
               //More than one? addFaavailability should exist.
               $faPerson->addFaavailability($availability);
    
               $em->persist($faPerson);
    
             }
    }
    $em->flush();