2012-04-19 173 views
1

这里指出:Doctrine 2.1 - Map entity to multiple tables Doctrine2不允许将一个对象映射到多个表格。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表我不得不问:

  1. 这是不好的设计?我是否可以通过其他方式来优雅地解决这个问题?我知道其他的DMBS具有继承,但是例如PostgreSql仍然不允许我加入base_entity来指出是否没有儿童的物理base_entity。

  2. 我可以做这样的事情在代码方面:

    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(); 
        } 
    } 
    

    这样的实体将表现得像一个单一的实体(不是从基地和子组合)到外面的世界,但它仍然要求我写一个单独的BaseEntity类和所有的配置信息将它连接到其他实体类

基本上,我问的是:这是一个Db的设计问题,我是从完全错误开始(如果我做了,这是“最好的”方法),或者这是一个代码问题,我应该用代码解决它(如果是这样,我的方法在2。好吧,还是有更好的方法来处理这个问题),有没有ORM允许多表映射?

非常感谢提前。

回答

2

您可以使用Class Table Inheritance(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; 
    } 

    ... 
} 
+0

感谢这个,我想我错过了文档的一部分。无论如何,这将完成我想要的。 – Pinetree 2012-04-21 15:54:35