我已阅读 Doctrine 2 Inheritance Mapping with Association但是说如果你需要 Animal
本身就是一个实体,比如创建选项列表。
在这种情况下,Pet
的鉴别器列位于 animal 表
的物种列中。
所以类应该是这样的。
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
}
我看到了几个问题。
animal
表没有指向owner
的外键。所以$pets
关联将不起作用。Animal
和Pet
或多或少是同一件事。如果有人 更改Animal
中的某些内容,这些更改不会反射(reflect)在 任何Pet
子类。
第一个问题的可能解决方案是有一个名为pet
的额外表,但是关联仍然存在问题,因为鉴别器列仍在animal
表并复制 pet
中的列会破坏规范化。
最佳答案
我不确定是否完全理解您的问题,但我会试一试:
Pet
是一种Animal
,在您的类层次结构中使其显式显示 是有意义的。请注意,抽象 类Pet
可以子类化 具体 类Animal
。这样,您仍然可以实例化Animal
、Dog
或Cat
,但不能实例化Pet
;Animal
根类可以有自己的鉴别器值,这使得用 Doctrine 持久化它成为可能。然后,您可以创建并保留Dog
或Cat
,甚至是通用的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_id
从Dog
和Cat
移动到Animal
表; - 从
Dog
和Cat
表中删除animal_id
;它们将与Animal
表共享id
值(一对一)。
关于php - Doctrine 2 具体表继承与关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8267500/