通过Doctrine2中实体与其存储库之间的事件进行通信

时间:2011-10-24 09:20:34

标签: events entity doctrine-orm

我开始在具有“Group”实体的项目中使用Doctrine 2,该实体可以从另一个Group继承,具有以下架构:id | parent_id | name

由于层次结构可以深入,我使用链接表“group_group”,使用此架构:ancestor_id | descendant_id | depth

这个想法是任何组都链接到它的所有祖先和后代,depth字段表示关系的距离,因此我不必使用许多SQL迭代父项或子项请求,单个请求可以获得所有结果。 我尝试使用Doctrine的ManyToMany关系,但我无法通过depth字段对它进行排序,因此我使用实体的存储库来获取相关的祖先和后代。

因为实体无法访问其存储库,所以我想知道实体是否有办法分派可由其存储库监听的事件,以便当实体尝试访问其祖先/后代时,存储库可以响应吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

Entity不应具有对Repository的具体引用,但定义Interface并让您的Repository实现此接口并没有任何问题将其注入Entity

与此解决方案类似Doctine 2 Restricting Associations with DQL

interface TreeInterface
{
   public function findParent();
   public function findChildren();
}

然后你的实体。

class Group
{
    $repository;

    setRepository(TreeInterface $repository)
    {
        $this->tree = $repository;
    }

    public function getParent()
    {
        return $this->repository->findParent($this);
    }

    public function getChildren()
    {
         return $this->repository->findChildren($this);
    }
}

class GroupRepository extends EntityRepository implements TreeInterface
{
    public function findParent(Group $group)
    {
        return //stuff
    }

    public function findChildren(Group $group)
    {
        return //stuff
    }
}

你用这种方式。

$group = $em->find('Group', 1);
$group->setRepository($em->getRepository('Group'));
$children = $group->getChildren();

为避免每次有孩子时都设置存储库,我会看一下EventManager和postLoad事件,看看是否可以在加载时将TreeInterface注入实体。