2012-04-19 3 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, чтобы разрешить соединение с каждым дочерним объектом в несколько состояний.

Мне не нужен класс BaseEntity, но мне нужно, чтобы каждый дочерний Entity имел метод getStates(). Конечно, у меня может быть класс абстрактных сущностей, но конкретные сущности будут расширять его, не иметь его как свойство, как если бы я наметил их, так как можно было бы сопоставить другие отношения один к одному.

Поскольку доктрина будет не позволяют мне карту 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. ok, или есть ли лучшие способы справиться с этим), и существуют ли ORM, которые допускают множественное сопоставление таблиц?

Большое спасибо заранее.

ответ

2

Вы можете использовать Наследование классов таблицы (see Doctrine documentation about that), определяя класс сущности BaseEntity и создавая EntityOne и EntityTwo, расширяющие это. Вы можете определить взаимосвязь между классом BaseEntity и классом сущности State как ассоциацией «один ко многим» - если я правильно понял, что вы хотели, предоставив необходимый метод getState() в классе BaseEntity.

Что-то вроде этого:

/** 
* @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

Смежные вопросы