我有一个导入脚本,它读取 XML 文件并将数据添加到 MySQL 数据库。xml 文件包含匹配数据和相关事件。
我有以下实体
- MatchList(不是最好的名字,而是其他主题)
- 比赛事件
我的问题的相关关系:
MatchList 内部(反面)
/**
* @OneToMany(targetEntity="MatchEvent", mappedBy="match", orphanRemoval=true)
*/
private $events;
public function __construct($uId)
{
$this->setId($uId);
$this->events = new ArrayCollection();
}
MatchEvent 内部(拥有方)
/**
* @ManyToOne(targetEntity="MatchList", inversedBy="events")
* @JoinColumn(name="match_id", referencedColumnName="id")
*/
private $match;
在导入脚本中,每个匹配项都有一个循环。在循环内部,我想删除当前分配给该匹配的所有事件。就在我想将 xml 文件中的新事件添加到此匹配项之后。
事件应从数据库中完全删除。不仅是对比赛的引用。
一个简化的例子
XML 内容
Match1
EventA
EventC
EventF
导入前
Match1
EventA
EventB
导入后应该是这样的
Match1
EventA
EventC
EventF
所以一个事件可能是
- 删除+添加(事件A)。
- 删除(事件B)
- 添加(事件F)
这是因为 XML 包含事件的更新或更正。因此,唯一可靠的方法是删除所有分配的事件并从最新的 xml 添加当前有效的事件。
我的问题是删除部分连同立即添加。它自己的每项任务都在工作。
我尝试了不同的方法(也阅读了学说文档),但我无法让它发挥作用。
遵循脚本的相关部分以及我尝试过的一些变体(注释掉)(不是整个代码。看“...”我希望这足以理解我的问题/错误)
try
{
foreach($matches as $matchNode)
{
$match = new \MatchList($matchNode['uID']);
...
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$match->removeEvent($previousEvent);
//$previousEvent->setMatch(null);
//$this->em->remove($previousEvent);
//$this->em->persist($previousEvent);
}
foreach($teamData->Goal as $goal)
{
...
$event = new \MatchEvent($match);
$event->setPlayer($player);
$event->setType($goal['Type']);
$event->setPeriod($goal['Period']);
$this->em->persist($event);
$match->addEvent($event);
}
...
$this->em->persist($match);
}
$this->em->flush();
}
catch(Exception $e){}
无论我尝试过什么,它都没有按预期工作。有时我得到一个错误(缺少级联持续存在)或没有发生错误但也没有删除。只有当我一次执行一项任务(删除或添加)时它才有效。
我知道仅对反面所做的更改不会被教义保存,因此我尝试在 MatchEvent 实体上调用 remove。或尝试取消设置整个 ArrayCollection 并使用 orphanRemoval 也删除实体。
我坚持尝试。我希望有人可以帮助我了解我做错了什么以及正确的方法。
谢谢
编辑
添加我尝试过的每个变体可能会有所帮助。
变体 1)
之后不添加实体:从数据库中删除事件(好)
在之后添加实体:错误:通过关系“MatchList#events”找到了一个新实体,该关系未配置为实体的级联持久操作:MatchEvent@XYZ。(坏的)
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$this->em->remove($previousEvent);
}
变体 2)
之后不添加实体:从数据库中删除事件(好)
在之后添加实体:错误:通过关系“MatchList#events”找到了一个新实体,该关系未配置为实体的级联持久操作:MatchEvent@XYZ。(坏的)
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$previousEvent->setMatch(null);
$this->em->remove($previousEvent);
$this->em->detach($previousEvent);
}
变体 3)
之后没有添加实体:错误:通过关系“MatchList#events”找到了一个新实体,该关系未配置为实体的级联持久操作:MatchEvent@XYZ。(坏的)
之后添加实体:未尝试,因为即使删除也没有奏效。
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$previousEvent->setMatch(null);
$this->em->detach($previousEvent);
}
这应该有效,否则我误解了这个: http ://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/faq.html#i-call-clear-on-a-one-to-许多集合但实体未删除
变体 4)
之后没有添加实体:数据库中的数据翻倍,因为没有删除任何事件,并且所有事件都以 match_id NULL 插入。(坏的)
之后添加实体:未尝试,因为即使删除也没有奏效。
$previousEvents = $match->getEvents();
foreach($previousEvents as $previousEvent)
{
$previousEvent->setMatch(null);
$this->em->detach($previousEvent);
$this->em->persist($previousEvent);
}