这个问题与我这里的另一个问题有点相关ArrayCollection (Doctrine)包含函数返回不正确的结果,所以如果有人想要更多关于我的问题的信息,它在那里,虽然这不是严格相同的问题。
现在,到这一点,我有一个FileSystemFolder模型一个文件夹,和一个FileProxy模型一个文件,FileSystemFolder包含一个FileProxy的ArrayCollection,我也有一个FileManager,执行移动操作,你会期望在任何文件系统上都有。这个移动操作需要两个文件系统文件夹和一个文件代理,从一个文件系统文件夹中删除这个文件代理,并将其添加到另一个文件系统文件夹中。
下面是这个函数:
public function moveFileProxy(FileSystemFolder $from, FileSystemFolder $to, FileProxy $proxy, $force = false)
{
if (!$this->checkFolder($from))
{
return array('type' => 'error', 'message' => 'Cannot move from this folder.');
}
if (!$force)
{
if (!$this->checkFolder($to))
{
return array('type' => 'error', 'message' => 'Cannot move to this folder.');
}
}
/*$return = "";
foreach($from->getFiles() as $file)
{
$return .= $file->getFilename() . " --- ";
}
if(!$from->getFiles()->contains($proxy))
{
return array('type' => 'error', 'message' => 'Folder '.$from->getName().' does not contain '.$proxy->getFilename(). ' All files from this folder '. $return);
}
if($to->getFiles()->contains($proxy))
{
return array('type' => 'error', 'message' => 'Folder '.$to->getName().' already contains '.$proxy->getFilename());
}*/
$from->removeFile($proxy);
$to->addFile($proxy);
return array('type' => 'pass', 'message' => 'Operation Successful.');
}
注释掉的代码属于另一个问题。检查不重要。
为了回答这个问题,我将从另一个问题中抄一条信息,因为它很重要,在这里:
/**
* @ORMManyToMany(targetEntity="FileProxy", fetch="EXTRA_LAZY")
* @ORMJoinTable(name="file_system_folders_files",
* joinColumns={@ORMJoinColumn(name="file_system_folder_id", referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="proxy_id", referencedColumnName="id", unique=true)})
*/
protected $files;
:
/**
* Add proxy
*
* @param FileProxy $proxy
* @return FileSystemFolder
*/
public function addFile(FileProxy $proxy)
{
if(!$this->getFiles()->contains($proxy))
{
$this->getFiles()->add($proxy);
}
return $this;
}
/**
* Remove proxy
*
* @param FileProxy $proxy
* @return FileSystemFolder
*/
public function removeFile(FileProxy $proxy)
{
if($this->getFiles()->contains($proxy))
{
$this->getFiles()->removeElement($proxy);
}
return $this;
}
现在,这些函数是非常直接的,它们真的不做任何花哨的事情,就像它们的名字告诉我们的那样,有趣的是,moveFileProxy函数工作得非常好(我坚持两个文件夹的这个函数,我认为这是一个很好的做法)。
问题是:这个函数实际上应该工作吗?正如你所看到的,$files变量是一个ArrayCollection,它没有级联持久化,它没有级联任何东西,但是这个函数仍然有效。
下面是显示整个过程的一段代码:
$result = $fm->moveFileProxy($origin, $destination, $upload);
if($result['type'] === 'error')
{
return JsonResponse::create($result);
}
$em = $this->getDoctrine()->getManager();
$em->persist($origin);
$em->persist($destination);
$em->flush();
但是它在大多数情况下工作,大多数情况下它不会抛出错误,但有时,在一些奇怪的情况下,它会抛出"重复条目异常",这也很奇怪,因为这毕竟是一个移动操作。
如果你知道任何关于这个问题,请帮助我,#symfony和#doctrine IRCs在帮助方面真的很糟糕。
谢谢。
看起来,我发现了这个问题的答案
(完全是偶然的),但我不完全确定,我不认为它记录在Doctrine文档中。它可能隐藏在代码的某个地方,我可能稍后会查找它来证明这个理论。
单向多对多关联创建了一个额外的表,因此该关联由3个表组成,没有实际的多对多关联,这2个表显然是您用来形成关联的表,但第三个表很重要。
第三个表是Doctrine当场创建的,尽管我们用@JoinColumn指定了列的属性,但我认为Doctrine实际上会进一步修改它们以实现级联持久化,因为否则就没有实际意义了。
我也很确定,它实际上是级联的,但就像我说的,这只是一个理论。