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()
.
来加载文件
我不喜欢的是,每次我想添加另一个具有 OneToMany
和 File
的实体时,它都会在数据库中创建一个新列,因此我可能有 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 来引用 Entity1
和 Entity2
。当调用 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
因为现在文件可能有很多实体。
处理具有多个 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()
.
我不喜欢的是,每次我想添加另一个具有 OneToMany
和 File
的实体时,它都会在数据库中创建一个新列,因此我可能有 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 来引用 Entity1
和 Entity2
。当调用 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
因为现在文件可能有很多实体。