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

发布于 2024-12-12 00:03:13 字数 431 浏览 0 评论 0原文

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

由于层次结构可以深入,因此我使用链接表“group_group”,并使用以下架构:ancestor_id | 后代 ID |深度

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

因为实体无法访问其存储库,所以我想知道是否有一种方法可以让实体调度其存储库可以侦听的事件,以便当实体尝试访问其祖先/后代时,存储库可以响应?

感谢您的帮助。

I'm starting to use Doctrine 2 in a project with a "Group" entity that can inherit from another Group, having the following schema: id | parent_id | name

Because the hierarchy can go deep, I use a linking table, "group_group", using this schema: ancestor_id | descendant_id | depth

The idea is that any group is linked to all of its ancestors and descendants, and the depth field indicates the distance of the relationship, so that I don't have to iterates through parents or children using many SQL requests, a single one can get all the results.
I tried to use Doctrine's ManyToMany relation but I could not get it to be ordered by the depth field, so instead I use the entity's repository to get the related ancestors and descendants.

Because an entity can not access its repository, I would like to know if there is a way for an entity to dispatch events that can be listened by its repository, so that when an entity tries to access its ancestors/descendants, the repository can respond?

Thanks for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尘曦 2024-12-19 00:03:14

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

与此解决方案类似 Doctine 2 限制与 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 注入到实体中。

An Entity shouldn't have a concrete reference to a Repository but there isn't anything wrong with defining an Interface and have your Repository implement this interface and injecting it into the Entity.

Similar to this solution Doctine 2 Restricting Associations with DQL

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

Then your Entities.

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
    }
}

And you use it this way.

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

To avoid setting the repository each time you get a child, I would take a look at the EventManager and postLoad event and see if you can inject a TreeInterface into the Entity on load.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文