Symfony:处理文件实体

Symfony: Handling file entity

处理具有多个 ManyToOne 关系的 File 实体的最佳方法是什么。

假设我有 5 个实体与 File 实体有 OneToMany 关系。

File.php

/**
 * @ORM\ManyToOne(targetEntity="Entity1", inversedBy="files")
 * @ORM\JoinColumn(name="entity1_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
 */
private $entity1;

 /**
 * @ORM\ManyToOne(targetEntity="Entity2", inversedBy="files")
 * @ORM\JoinColumn(name="entity2_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
 */
private $entity2;

and so one.... 

Entity1.php

  /**
 * @ORM\OneToMany(targetEntity="File", mappedBy="entity1" , cascade={"persist", "remove"}, orphanRemoval=true)
 */
protected $images;

上面的好处是设置了getter和setter,我可以自动持久化并保存到数据库。关系已设置,我可以通过调用 $entity1->getFiles().

来加载文件

我不喜欢的是,每次我想添加另一个具有 OneToManyFile 的实体时,它都会在数据库中创建一个新列,因此我可能有 10 个列引用来自其他实体的 ID。

我想要实现的是在 class 字段中保存实体的 class 并将记录的 id 保存在 id 字段中但是还以某种方式仍然允许持久保存和集合保存工作。

entity_id | class
------------------------------------------
2         | ProjectBundle/Entity/Entity1
3         | ProjectBundle/Entity/Entity2

您根本不需要 class 字段。

通过为您要从 File 引用的所有实体创建基础 class 使用 Doctrine's inheritance mapping

/**
 * @ORM\Entity()
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="entityType", type="string")
 * @ORM\DiscriminatorMap({
 *      "entity1" = "Entity1",
 *      "entity2" = "Entity2"
 * })
 */
abstract class BaseEntity
{
    /**
     * @ORM\ManyToMany(targetEntity="File", mappedBy="entities" , cascade={"persist", "remove"}, orphanRemoval=true)
     */
    protected $images;
}

/**
 * @ORM\Entity
 */
class Entity1 extends BaseEntity
{
    ...
}

/**
 * @ORM\Entity
 */
class Entity2 extends BaseEntity
{
    ...
}

这样您就可以通过 File 的基数 class 来引用 Entity1Entity2。当调用 getEntities 时,Doctrine 根据每个实体的鉴别器值创建正确的 class "automatically" 的实例。

File

/**
 * @ORM\ManyToMany(targetEntity="Entity", inversedBy="images")
 * @ORM\JoinColumn(name="entity_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
 */
 protected $entities;

OneToMany, ManyToOne 变为 ManyToMany 因为现在文件可能有很多实体。