0

我有一个class Employee extends Person. 随着时间的推移,一个已经存在的Person可以成为Employee公司的一个。

我知道使用原始 SQL 更改鉴别器类型或使用晦涩的 PECL 扩展进行类型转换是一种不好的做法。

但是是否有一种设计模式可以管理这些复杂性?

是克隆所有属性和关系(Person 与其他实体有很多关系)来实现这一目标的唯一方法吗?我将如何克隆现有的人及其所有关系?

4

2 回答 2

3

由于PersonEmployee是两个不同的“事物”,因此您应该创建一个与 Person 实体具有一对一关系的 Employee 实体。这意味着 Employee 始终是 Person,但 Person 不一定是 Employee。

class Employee
{
    /**
     * @ORM\OneToOne(targetEntity="Acme\PersonBundle\Entity\Person", cascade={"persist"})
     * @ORM\JoinColumn(referencedColumnName="id", nullable=true)
     */
    protected $person;
}

这不仅允许您保留 Person 实体及其所有现有属性,避免克隆数据(这绝不是一个好主意),而且最重要的是分离了两种对象类型。

正如@Zeljko 提到的,您可以创建一个类型字段字段,但我相信我对数据进行规范化的方法要干净得多。如果您需要多种类型的员工,那么您可以创建一个 EmployeeType 表,然后在 Employee 实体中拥有一个 EmployeeType_ID。这种方法比使用常量更干净,后者往往会变得混乱且难以维护。

于 2013-06-06T13:45:19.580 回答
1

克隆数据是个坏主意。记住:如果你在复制一些东西,你就做错了:)

我认为最好的解决方案是根本不使用继承。只需在名为例如的 Person 实体中创建新列。type这将是一个常数。在该实体中,放置如下内容:

class Person
{
    const TYPE_USER = 0 ;
    const TYPE_EMPLOYEE = 1 ;
    const TYPE_BIG_FAT_BOSS = 2 ;
    ...

    /**
    * @ORM\Column(type="integer")
    */
    protected $type = self::TYPE_USER ;

这样您只需要更新type列并拥有更好的功能。

于 2013-06-06T13:19:43.480 回答