如何在同一个实体的学说中实现 parent child 关系?

How to implement parent child relation in doctrine with the same entity?

我尝试创建包含另一个 customElement 的关系 parent - child 比如三个,一个 parent 有很多 child 但 child 只有一个 parent.

<?php

namespace App\Entity;

use App\Repository\CustomElementRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass=CustomElementRepository::class)
 */
class CustomElement
{

    /**
     * @ORM\OneToMany(targetEntity=CustomElement::class, mappedBy="customElements")
     */
    private $customElements;

    public function __construct()
    {
        $this->customFields = new ArrayCollection();
        $this->customElements = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getCustomElement(): ?self
    {
        return $this->customElement;
    }

    public function setCustomElement(?self $customElement): self
    {
        $this->customElement = $customElement;

        return $this;
    }

    /**
     * @return Collection|self[]
     */
    public function getCustomElements(): Collection
    {
        return $this->customElements;
    }

    public function addCustomElement(self $customElement): self
    {
        if (!$this->customElements->contains($customElement)) {
            $this->customElements[] = $customElement;
        }

        return $this;
    }

    public function removeCustomElement(self $customElement): self
    {
        if ($this->customElements->contains($customElement))
            $this->customElements->removeElement($customElement);

        return $this;
    }
}

当我更新数据库时,我没有 ID 为 parent 的列。

请问我该如何解决这个问题?有学说可能吗?

谢谢

本质上,您 只需要一个 字段来建立 self-referencing 关系(many-to-one 在您的情况下)。

但是,您定义了 partner 字段 (one-to-many),但没有定义 owning 字段。每个关系都有一个拥有方,在本例中就是您设置单个 parent 元素的一方。

因此,如果您两者都想要(我想说,这是完全合理甚至有用的!):

/**
 * @ORM\ManyToOne(type="CustomElement", inversedBy="children")
 * @ORM\JoinColumn(name="parent_id", nullable=true)
 */
private $parent;
/**
 * @ORM\OneToMany(type="CustomElement", mappedBy="parent")
 */
private $children;

备注:

  • 注意 inversedBy 和 mappedBy 属性如何指向各自的其他属性。它告诉学说,那些 one-to-many/many-to-one 属于彼此。
  • 默认情况下,数据库列的命名方式为 ManyToOne 属性 名称 (parent) 加上 _id(因此 parent_id)。您可以使用 JoinColumn 注释中的 name 属性覆盖命名(如上所示)。如果数据库中的名称已经与生成的名称匹配,则可以省略它。
  • JoinColumn 的 nullable=true 确保您可以添加一个元素而不必强制它具有 parent,据我所知,self-referencing many-to-one 是必需的。
  • ManyToOne 是拥有 的一方。要为实体设置 children,您必须将其每个 $parent 属性设置为该实体。 (您可以 另外 添加 it/them 到实体的 $children 属性,如果您想立即使用它。否则 children 将在下次从数据库加载实体时加载)
  • 显然,在使用它之前,您需要更新数据库 structure/schema(最好通过迁移)

有关其他信息,请参阅有关关联映射的学说文档以及注释参考。