Doctrine 2 - наследование таблиц классов, выбор по типу - PullRequest
6 голосов
/ 20 февраля 2011

У меня есть две сущности - Новости и Пейдж. Определение выглядит так:

/**
 * Description of Page
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="type", type="string")
 * @DiscriminatorMap({
 *  "news" = "News" ,
 *  "page" = "Page"})
 *
 * @table(
 *  name="pages"
 * )
 */
class Page extends BaseEntity {...}
class News extends Page {...}

Я знаю, как выбирать только «новостные» сущности - просто SELECT ... FROM News n.

Но есть ли способ, как выбрать только "страницы" сущности, которые отображаются непосредственно в класс страницы? Или я должен создать для этого какую-то дополнительную страницу, расширяющую сущность?

Ответы [ 2 ]

12 голосов
/ 22 февраля 2011

Решением является использование x INSTANCE OF Entity в предложении WHERE.

http://groups.google.com/group/doctrine-user/browse_thread/thread/b1dc52ed447204e2

1 голос
/ 20 апреля 2012

Решение, которое я использую, заключается в том, что я создаю Switcher для корневого объекта Repository, например, так:

class PageRepository extends EntityRepository
{
  protected $_switchEntityNameSave = null;

  /**
   * @param type $fqcn 
   */
  protected function _swapEntityDiscriminator($fqcn = null){
    if(isset($fqcn)){
       $this->_switchEntityNameSave = $this->_entityName;
       $this->_entityName = $fqcn;
    } else {
       $this->_entityName = $this->_switchEntityNameSave;
       unset($this->_switchEntityNameSave);
    }
  }

  // ... AND TO USE... 

  public function findSomeStuff()
  {
    $this->_swapEntityDiscriminator(News::getFqcn());
    // The query, the result in a variable, $q for example
    $this->_swapEntityDiscriminator();
    return $q->getQuery();
  }

}

Затем в родительском классе я получаю Getter getFqcn()Примерно так:

abstract class BaseEntity {
  /**
   * Get fqcn
   * 
   * Fully Qualified Class Name
   *
   * @return string
   */
  public static function getFqcn()
  {
      return get_called_class();
  }
  // ...
}

, использующие функцию позднего статического связывания и дающие мне полное имя класса для конкретного объекта (либо News, либо Page).

Я делаюпоставить абстрактные, чтобы не создавать их экземпляры.

Что я также добавлю в конкретные классы, несколько констант:

class News extends Page {
  const HUMAN_READABLE = "News";
  const DISCRIMINATOR = "news";   // SAME as your @DiscriminatorMap() Annotation.

}

Таким образом, мой Repository я могу создать специализированныйискатели только по одному из типов.

...