理论对称中的许多关系操作


OneToMany relation operations in doctrine-symfony

我不清楚如何处理OneToMany方面的操作。

假设对象A在ManyToOne一侧,对象B在OneToMany一侧。

  1. 我想在创建对象B时,将许多对象A分配给它-我的解决方案是获取A对象并分配给它们B对象

  2. 我想在删除对象B时,将对象中的所有引用设置为nullA -从研究中我发现我可能需要加一个ondelete="setNull"功能表

是否有更好的方法(或一般的替代方法)来处理这种情况?

use Doctrine'ORM'Mapping as ORM;
class AObject
{
    // ...
    /**
     * @ORM'ManyToOne(targetEntity="AppBundle'Entity'BObject", inversedBy="a", onDelete="SET NULL")
     */
    private $b;
}
class BObject
{
    // ...
    /**
     * @ORM'OneToMany(targetEntity="AppBundle'Entity'AObject", mappedBy="b", cascade={"persist"})
     */
    private $a;
    public function __construct()
    {
        $this->a = new 'Doctrine'Common'Collections'ArrayCollection();
    }
    /**
     * @return 'Doctrine'Common'Collections'ArrayCollection
     */
    public getA()
    {
        return $this->a;
    }
    /**
     * @param 'Doctrine'Common'Collections'ArrayCollection $a
     */
    public setA($a)
    {
        $this->a = $a;
    }
    /**
     * @param AObject $a
     * @return BObject
     */
    public addA($a)
    {
        $this->a[] = $a;
        $a->setB($this); // assign B object to A
        return $this; // For method chaining
    }
    /**
     * @param AObject $a
     */
    public removeA($a)
    {
        $this->a->removeElement($a);
    }
}

对于1)你仍然需要获取你的对象,你的代码不能神奇地知道哪个A对象分配给你的新B对象。

使用上面定义的类B,您可以编写
$b = new BObject();
$b
    ->addA($a1)
    ->addA($a2)
    ->addA(new AObject());
$entityManager->persist($b);
$entityManager->flush();

和A对象都有对b的引用

对于2)这是一个更好的解决方案,处理到数据库级别

根据您的需要,您可以使用教义生命周期事件。

对于示例,首先需要定义事件侦听器:
# /src/FooBundle/Resources/config/services.yml
services:
# Event subscribers
foo.bar.subscriber:
    class: FooBundle'EventListener'BarSubscriber
    tags:
       - { name: doctrine.event_subscriber }

然后创建一个:

// FooBundle'EventListener'BarSubscriber.php
namespace FooBundle'EventListener;
use Doctrine'Common'EventSubscriber;
use Doctrine'ORM'Event'LifecycleEventArgs;
class BarSubscriber implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(
            'preRemove',
            'postPersist',
        );
    }
    // This method will be executed on each entity, before it has been deleted
    // You can do here what u want in your second paragraph
    public function preRemove(LifecycleEventArgs $args) 
    {
        $entity = $args->getEntity();
        // Do not forget to check your entity type
        if (!$entity instanceof SomeInterface) {
            return;
        }
        // Some code that handle some actions on related entites
    }
    // This code will be executed after each entity creation
    // Here you can add more relations for your main entity
    public function postPersist(LifecycleEventArgs $args) 
    {
        $entity = $args->getEntity();
        if (!$entity instanceof TimestampableInterface) {
            return;
        }
        // Some actions on relations, after the establishment of the main object
    }
}

另外,您还可以使用Doctrine级联操作来删除所有子实体