【问题标题】:Doctrine 2 Concrete Table Inheritance with AssociationsDoctrine 2 带有关联的具体表继承
【发布时间】:2012-01-06 05:44:18
【问题描述】:

我已阅读 Doctrine 2 Inheritance Mapping with Association,但如果您需要 Animal 本身成为一个实体,例如创建选项列表。

在这种情况下,Pet 的鉴别器列位于 animal table 的物种列中。

所以类应该是这样的。

class Animal
{
    $id;
    $species;
}

/**
 * @Table(name="animal")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="species", type="string")
 * @DiscriminatorMap({"dog" = "Dog", "cat" = "Cat"})
 */
abstract class Pet
{
    $id
    $species;
}

class Dog extends Pet { }

class Cat extends Pet { }

class Owner 
{
    /**
     * @OneToMany(targetEntity="Pet")
     */
    $pets
}

我发现了几个问题。

  1. animal 表没有owner 的外键。所以 $pets 关联不起作用。

  2. AnimalPet 或多或少是同一件事。如果有人 更改 Animal 中的某些内容这些更改不会反映在 任何Pet 子类。

第一个问题的一个可能解决方案是有一个名为pet 的额外表,但关联仍然存在问题,因为鉴别器列仍在animal 表中,并且复制了@ 中的列987654337@ 会破坏规范化。

【问题讨论】:

    标签: php inheritance orm doctrine-orm concrete-inheritance


    【解决方案1】:

    我不确定是否完全理解您的问题,但我会尝试一下:

    • PetAnimal在类层次结构中明确说明 是有意义的。请注意,abstractPet 可以继承 concreteAnimal。这样,您仍然可以实例化AnimalDogCat,但不能实例化Pet
    • Animal 根类可以有它自己的鉴别器值,这使得它可以与 Doctrine 保持一致。然后,您可以创建并保留 DogCat,甚至是通用 Animal
    • Animal 需要对其所有者的引用
    • Owner 现在与Animal 具有一对多关系
    • species 列是一个鉴别器,它对你的领域模型没有任何价值(类名会告诉你正在处理哪个 Animal),所以我建议移除此属性。

    最后一点,你真的需要Pet 类吗?如果 Pet 没有特定于 Animal 的内容(即类为空),那么您可能应该将其从类层次结构中删除。

    class Owner {
        /**
         * @OneToMany(targetEntity="Animal")
         */
        protected $animals;
    }
    
    /**
     * @Table(name="animal")
     * @InheritanceType("JOINED")
     * @DiscriminatorColumn(name="species", type="string")
     * @DiscriminatorMap({"animal" = "Animal", "dog" = "Dog", "cat" = "Cat"})
     */
    class Animal {
        /** @Id @Column(type="integer") @GeneratedValue */
        protected $id;
    
        /** @ManyToOne(targetEntity="Owner") */
        protected $owner;
    }
    
    abstract class Pet extends Animal {
        // Do you really need this class?
    }
    
    class Dog extends Pet {
        // ...
    }
    
    class Cat extends Pet {
        // ...
    }
    

    关于您的数据库结构,我提出以下更改:

    • owner_idDogCat 移动到Animal 表中;
    • DogCat 表中删除animal_id;他们将与Animal 表共享id 值(一对一)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多