如何在同一个实体的学说中实现 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(最好通过迁移)
有关其他信息,请参阅有关关联映射的学说文档以及注释参考。
我尝试创建包含另一个 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(最好通过迁移)
有关其他信息,请参阅有关关联映射的学说文档以及注释参考。