如此处所指出:Doctrine 2.1 - Map entity to multiple tables Doctrine2不允许将一个对象映射到多个表。
我目前有类似的Mysql数据库设置:
base_entity: id, some_basic_data_columns
state: id, state, entity_id (FK to base_entity.id), start_time, end_time, ...
entity_one: id (FK to base_entity.id), some_specific_data
entity_two: id (FK to base_entity.id), some_specific_data
and so on...
在某种程度上,entity_x是“扩展”base_entity,所有这些实体都可以有多个状态。要拥有正确的外键,我必须要么有单独的状态表(我不想这样做,因为它们在结构上是相同的),或者这样做。
基本实体本身是无用的,id甚至可以归结为id字段,以允许将每个子实体连接到多个状态。
我不需要BaseEntity类,但我确实需要每个子实体都有一个getStates()方法。当然,我实际上可能有一个抽象的实体类,但是具体的实体会扩展它,而不是将它作为一个属性,就像我将它们映射为一个可以映射其他一对一关系的那样
由于Doctrine不允许我将EntityOne映射到entity_one和base_entity表,我不得不问:
这是不好的设计?我是否会忽略其他一些优雅的方法来解决这个问题?我知道其他DMBS都有继承,但是例如如果孩子没有物理base_entity,PostgreSql仍然不允许我加入base_entity来声明。
我可以在代码方面做这样的事情:
class EntityOne {
// baseEntity as a property
private $_baseEntity;
// private getter for the base table
private getBaseEntity();
// and getters like this for properties in the base table
public getStates(){
return $this->getBaseEntity()->getStates();
}
}
这样,实体的行为就像一个单独的实体(不是从base和child组合)到外部世界,但它仍然需要我编写一个单独的BaseEntity类和所有配置信息来将它连接到其他实体类
基本上,我要问的是:这是一个Db设计问题,我从一开始就完全错了(如果我这样做,这是“最佳”方法),或者这是一个代码问题,我应该用代码解决它(如果是这样,我的方法是2.好的,还是有更好的方法来解决这个问题),是否有允许多表映射的ORM?
非常感谢提前。
答案 0 :(得分:2)
您可以使用类表继承(see Doctrine documentation about that),定义BaseEntity实体类,并创建扩展它的EntityOne和EntityTwo。 你可以将BaseEntity类和State实体类之间的关系定义为一对多关联 - 如果我理解你想要的,在BaseEntity类中提供所需的getState()方法。
这样的事情:
/**
* @Entity
* @Table(name="base_entity")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="entity_type", type="string")
* @DiscriminatorMap({"entity_one"="EntityOne", "entity_two"="EntityTwo"})
*/
class BaseEntity {
/**
* @Id
* @Column(type="integer")
*/
protected $id;
/**
* @OneToMany(targetEntity="State", mappedBy="entity)
**/
protected $states;
public function getStates() {
return $this->states;
}
...
}
/**
* @Entity
* @Table(name="entity_one")
*/
class EntityOne extends BaseEntity {
...
}
/**
* @Entity
* @Table(name="entity_two")
*/
class EntityTwo extends BaseEntity {
...
}
/**
* @Entity
* @Table(name="state")
*/
class State {
/**
* @ManyToOne(targetEntity="BaseEntity", inversedBy="states")
* @JoinColum(name="entity_id", referencedColumnName="id")
*/
protected $entity;
public function getEntity() {
return $this->entity;
}
...
}