2013-08-01 4 views
0

Учитывая следующие объекты:Doctrine ORM и наследование

class Entity { 
    protected $id; 
} 
class User extends Entity { 
    /** @var Entity */ 
    protected $target; 
} 
class Document extends Entity { 
    protected $title; 
} 
class Report extends Entity { 
    protected $level; 
} 

Что отображение мне нужно, чтобы создать таким образом учение можно сопоставить User объект правильно. Проблема заключается в том, что я хочу иметь User::$target использовать любой объект (следовательно, подсказку типа Entity), а позже код сможет ответить соответствующим образом, в зависимости от того, является ли это Document или Report.

Это также означает, что в коде, мне нужно, чтобы быть в состоянии принести либо Entity::$title если это Document или Entity::$level если это Report.

Могу ли я достичь этого с помощью доктрины?

ответ

1

Это должно работать нормально. Я не добавлял аннотации по умолчанию, такие как «@ORM \ Entity» (http://docs.doctrine-project.org/en/latest/reference/annotations-reference.html). Надеюсь, это то, что вы ищете, в противном случае дайте мне знать.

/** 
* @ORM\InheritanceType("SINGLE_TABLE") 
*/ 
class Entity { 
    protected $id; 
} 

class User extends Entity { 
    /** 
    * @ORM\ManyToOne(targetEntity="Entity") 
    * @var Entity 
    */ 
    protected $target; 
} 

Посмотрите: http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html Вы должны использовать единичное наследование по вопросам из-за производительности Таблица наследования классов.

В противном случае Doctrine сделает соединения над дочерними таблицами таблицы сущностей, потому что Doctrine не знает, какой тип имеет «Entity». Что-то вроде:

SELECT t1.id, t2.title, t3.level FROM entity t1 LEFT JOIN document t2 ON t2.id = t1.id LEFT JOIN report t3 ON t3.id = t1.id 

Больше дочерних таблиц приведет к большему количеству объединений -> медленному.

Вот как вы проверяете, является ли цель документом или отчетом, и для определения того, к какому полю вы должны получить доступ.

// loads all users 
$users = $this->em->getRepository('User')->findAll(); 
foreach($users as $user){ 
    $target = $user->getTarget() 
    if($target instanceof Document){ 
     echo $target->getTitle(); 
    } 
    else if($target instanceof Report){ 
     echo $target->getLevel() 
    } 
} 
Смежные вопросы