Symfony 修改父实体时删除子实体

Symfony 修改父实体时删除子实体,symfony,doctrine-orm,Symfony,Doctrine Orm,我正在控制器中执行修改文件操作。子entityStrOrigin与文件实体具有以下关系: /** * @ORM\ManyToOne(targetEntity="File" ) * @ORM\JoinColumn(name="STOR_FILE", referencedColumnName="id", onDelete="CASCADE") */ 现在,在控制器中的修改操作中,我获取要修改的文件,设置表单并进行一些测试,然后上载文件,持久化文件实体,并用新修改的文件覆盖StrOrigin,其中包

我正在控制器中执行修改文件操作。子entityStrOrigin与文件实体具有以下关系:

/**
* @ORM\ManyToOne(targetEntity="File" )
* @ORM\JoinColumn(name="STOR_FILE", referencedColumnName="id", onDelete="CASCADE")
*/
现在,在控制器中的修改操作中,我获取要修改的文件,设置表单并进行一些测试,然后上载文件,持久化文件实体,并用新修改的文件覆盖StrOrigin,其中包含文件中的许多字符串。我被困在如何超越StrOrigin的问题上。在提交和保存新文件时,我已尝试删除旧文件:

 $this_file_STROR=$em->getRepository('File')->find(array('id'=>$idfile));
                    $em->remove($this_file_STROR);
                    $em->flush();

但这似乎不起作用。

跟进评论:

您不想删除实际文件。您误解了onDelete=CASCADE!这意味着删除文件时,所有StrOrigin也将被删除。这与你想要达到的目标无关

您需要的是以下内容:

$this_file_STROR=$em->getRepository('File')->find($idfile);
foreach($this_file_STROR->getStrOrigins() AS $strOrigin){
  $em->remove($strOrigin);
}
// now $this_file_STROR as no StrOrigins anymore
$em->flush();
/** 
* @ORM\ManyToOne(targetEntity="File" ) 
* @ORM\JoinColumn(name="STOR_FILE", referencedColumnName="id", orphanRemoval=true) 
*/

public function deleteStrOrigins(){
        $this->strOrigins = new ArrayCollection(); // you can also try to use = null. I'm using ArrayCollections, so this is my way and I never tried the null approach.
}

还要注意,此时不需要冲洗。刷新只是将当前对象持久化到数据库。只要使用对象,就不需要刷新。通常,您可以在脚本结束之前进行刷新,例如在控制器中调用render之前。如果多次刷新,应用程序可能会由于与数据库的交互而变慢。

我找到了另一种可能更快的解决方案:

它被描述为孤儿移除。其想法是简单地删除关联,并告诉条令,不再提及的相关实体将被删除。在您的情况下,您将执行以下操作:

$this_file_STROR=$em->getRepository('File')->find($idfile);
foreach($this_file_STROR->getStrOrigins() AS $strOrigin){
  $em->remove($strOrigin);
}
// now $this_file_STROR as no StrOrigins anymore
$em->flush();
/** 
* @ORM\ManyToOne(targetEntity="File" ) 
* @ORM\JoinColumn(name="STOR_FILE", referencedColumnName="id", orphanRemoval=true) 
*/

public function deleteStrOrigins(){
        $this->strOrigins = new ArrayCollection(); // you can also try to use = null. I'm using ArrayCollections, so this is my way and I never tried the null approach.
}
现在调用你的代码

$this_file_STROR=$em->getRepository('File')->find($idfile);
$this_file_STROR->deleteStrOrigins();
$em->flush();

应该删除所有相关的strorigin,只要它们在其他任何地方都不相关。

从数据库中删除整个文件对象。是否只想删除所有StrOrigin并添加新的StrOrigin?在侧节点上,当对具有主键的实体使用find时,您可以在不使用数组的情况下查找$idfile。是的,我想删除上一个文件的所有StrOrigin并用新文件替换它们。在我的代码中,我应该在哪里删除以前的文件?因为级联中有一个delete=on?谢谢。我不知道关于同花顺的事。但是这需要很多时间,因为单个文件可能包含大量StrOrigin。性能在这里至关重要!好啊上述方式就是条令文件中所说的应该采取的方式。似乎还有另一种方法。看看第9.7点:我找到了一个更好的方法。我将以前的文件$this_file实体存储在一个新对象中,删除$this_文件并填充新对象,然后将其持久化。因此,所有StrOr都将使用$this\u filekeeping onDelete=CASCADE删除: