在 Doctrine 冲洗中插入前删除

nim*_*ima 7 php mysql symfony doctrine-orm

我有一个 Case 实体,它可以有多个楼层(OneToMany),每个楼层都有一个指定其类型的 FloorType。我的 Floors 实体上也有一个 UniqueConstraint,它不允许每个 Case 有两个具有相同 FloorType 的 Floors。

为了将楼层插入到每个案例中,我为楼层创建了一个 Symfony 集合类型,并使用 js 将新楼层添加到我的案例中。

Symfony 的表单集合文档说如果一个项目没有提交,它会自动从数据库中删除。

现在的问题是,如果我在 DB 中已经有一个 Case 的 Floors,那么当我在表单中删除 Floor 并再次添加它时,它将被视为新的 INSERT,但是由于 Doctrine 通过首先执行 INSERT 来执行刷新和 DELETEs 最后,我会因为违反我设置的 uniqueConstraint 得到以下错误:

SQLSTATE [23000]:完整性约束违规:1062 键“floors_case_floor_type_unique”的重复条目“4-2”

这意味着在尝试从同一个表中删除最后一行之前,Doctrine 试图在 Floors 表中插入一行与被删除的具有相同 FloorType 的行。

有没有办法让学说在 INSERT 之前做 DELETE,或者有其他方法来解决这个问题?

fer*_*tor 0

一种方法是使用FormEvent
我建议您将 FormType 注册为服务,以便您可以注入学说

# in your services.yml:
services:
    yourbundle.form.case_type:
        class: Your\Bundle\CaseType
        arguments: ["@doctrine"]
        tags:
            - { name: form.type, alias: your_bundle_case_type }
Run Code Online (Sandbox Code Playgroud)

并扩展您的FormType

class CaseType /*...*/
{
    private $doctrine;

    public function __construct($doctrine)
    {
        $this->doctrine = $doctrine;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在您的方法中注册一个EventListenerbuildFormCaseType

$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
     $data = $event->getData();
     $em  = $this->doctrine->getEntityManager();

     foreach ($data['floor'] as $floor) {
         // delete floors here...
         $duplicateFloor = $em->find('YourBundle:Floor', $floor->getId);
         $em->remove($duplicateFloor);
     }
     $em->flush();
});
Run Code Online (Sandbox Code Playgroud)