PHP/Propel 删除记录 1:n

Posted

技术标签:

【中文标题】PHP/Propel 删除记录 1:n【英文标题】:PHP/Propel delete record 1:n 【发布时间】:2017-03-03 13:49:03 【问题描述】:

我有两个表:step 和 links 以 1:n 连接。我的目标是通过步骤对象维护链接。我从数据库中检索所有步骤并使用链接表填充关系。我持久化包含指向 JSON 的链接集合的 step 对象,并使用 REST 将其返回到前端。

这意味着如果一个步骤与前端的另一个步骤链接或取消链接,我会将整个步骤发送回后端,包括链接集合。在后端我使用以下代码:

public function put($processStep) 
        if (isset($processStep['Processesid']) && isset($processStep['Coordx']) && isset($processStep['Coordy'])) 
            $p = $this->query->findPK($processStep['Id']);

            $p->setId($processStep['Id']);
            $p->setProcessesid($processStep['Processesid']);
            if (isset($processStep['Flowid'])) $p->setFlowid($processStep['Flowid']);
            if (isset($processStep['Applicationid'])) $p->setApplicationid($processStep['Applicationid']);
            $p->setCoordx($processStep['Coordx']);
            $p->setCoordy($processStep['Coordy']);

            $links = $p->getLinksRelatedByFromstep();
            $links->clear();

            foreach ($processStep['Links'] as $link) 
                if (!isset($link['Linkid'])) 
                    $newLink = new \Link();

                    $newLink->setFromstep($link['Fromstep']);
                    $newLink->setTostep($link['Tostep']);

                    $links->prepend($newLink);
                
            

            $p->save();

            return $p;
         else 
            throw new Exceptions\ProcessStepException("Missing mandatory fields.", 1);
        
    

我基本上是从一个步骤中删除每个链接,并根据我重新创建链接的请求对象。这让我省去了比较删除和添加哪些链接的工作。插入工作就像一个魅力 Propel 会自动创建新链接。事情是它不会像插入那样删除。我检查了被持久化的对象 ($p),我看到链接被删除,但在 mysql 日志中,Propel 绝对没有执行任何操作。看起来链接集合中缺少的成员不会触发脏标志或类似的东西。

也许我的方法不对,希望有人能提供一些建议。

谢谢

【问题讨论】:

我不知道;在代码中的任何地方都看不到对 delete() 的任何调用。我只看到你使用 clear()。 clear() 清除您应用于集合的任何条件/过滤器,它实际上不会删除任何内容。 $links var 是 ObjectCollection 的一个实例,clear 函数从集合中删除链接(根据 API 文档),破坏了步骤与其链接之间的关系,至少那是我的推理:)。通过打破这种关系,我希望 Propel 会触发丢失链接对象的隐式删除,就像它触发添加到集合中的链接的插入一样。如果我要使用显式删除调用,我需要开始比较发布到后端的步骤中的链接和我希望阻止的数据库中的链接。感谢您的意见! 【参考方案1】:

要删除记录,您绝对必须始终使用delete。在确定需要添加、更新和删除哪些实体时,集合上的 diff 方法非常有用。

【讨论】:

谢谢 Ben,这就是我需要知道的全部内容。可惜我希望它足够直观,可以处理插入之类的删除【参考方案2】:

感谢 Ben,我走上了正确的道路,不需要明确调用删除。我遇到了一个名为:setRelatedBy(ObjectCollection o) 的函数我使用这个函数来提供相关对象的列表,新对象被解释为插入,遗漏被解释为删除。

我没有找到任何有关该问题的相关文档,所以这是我的代码:

$p = $this->query->findPK($processStep['Id']);

            $p->setId($processStep['Id']);
            $p->setProcessesid($processStep['Processesid']);
            $p->setCoordx($processStep['Coordx']);
            $p->setCoordy($processStep['Coordy']);
            if (isset($processStep['Flowid'])) $p->setFlowid($processStep['Flowid']);
            if (isset($processStep['Applicationid'])) $p->setApplicationid($processStep['Applicationid']);

            //Get related records, same as populaterelation
            $currentLinks = $p->getLinksRelatedByFromstep();
            $links =  new \Propel\Runtime\Collection\ObjectCollection();

            //Check for still existing links add to new collection if so.
            //This is because creating a new Link instance and setting columns marks the object as dirty creating an exception due to duplicate keys
            foreach ($currentLinks as $currentLink) 
                foreach ($processStep['Links'] as $link) 
                    if (isset($link['Linkid']) && $currentLink->getLinkid() == $link['Linkid']) 
                        $links->prepend($currentLink);

                        break;
                    
                
            

            //Add new link objects
            foreach ($processStep['Links'] as $link) 
                if (!isset($link['Linkid'])) 
                    $newLink = new \Link();

                    $newLink->setFromstep($link['Fromstep']);
                    $newLink->setTostep($link['Tostep']);

                    $links->prepend($newLink);
                

            

            //Replace the collection and save the processstep.
            $p->setLinksRelatedByFromstep($links);
            $p->save();

【讨论】:

以上是关于PHP/Propel 删除记录 1:n的主要内容,如果未能解决你的问题,请参考以下文章

hdu 2433 Travel

历史记录如何删除

查询及删除重复记录

怎样删除SAP的历史记录

怎样删除历史纪录。

为啥CKModifyRecordsOperation批量删除CloudKit中的记录不删除记录?