2011-02-19 8 views
5

두 개의 항목 - 뉴스와 페이지가 있습니다. 정의는 다음과 같습니다 : 전용 "뉴스"엔티티를 선택하는 방법을Doctrine 2 - 클래스 테이블 상속, 유형별로 선택

 
/** 
* 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 간단합니다.

페이지 클래스에 직접 매핑되는 "페이지"엔티티 만 선택하는 방법이 있습니까? 아니면 이것을 위해 페이지를 확장하는 추가 엔티티를 만들어야합니까?

+0

무엇을하려고합니까? 나는 당신이 적절한 방법으로 클래스 테이블 상속을 사용하고 있는지 확신하지 못한다. –

+0

제목, 텍스트, 저자 등의 속성을 가진 기본 항목 페이지가 있습니다. 뉴스는 요약, 주석 연결 등과 같은 몇 가지 추가 속성으로 확장됩니다. 단일 테이블 상속을 사용하여이 작업을 수행 할 수는 있지만 가능합니다. 결과가 하나의 큰 테이블이기 때문에 그것이 올바른 접근이라고 생각하지 않습니다. –

+0

나는 뭔가를 놓쳤는가? ... 왜'SELECT * FROM Page ... '를 쿼리 할 수 ​​있습니까? – Cobby

답변

11

해결책은 WHERE 절에서 x INSTANCE OF Entity을 사용하는 것입니다. 부모 CLASSE에, 나는 게터 getFqcn() 수행

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

} 

다음 :

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

0

이 솔루션은 내가 사용하는 것이 내가 지금처럼 루트 엔티티 Repository 클래스에 스위처를 만들 수 있다는 것입니다 이렇게 :

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 난 단지 유형 중 하나에 전문 측정기를 만들 수 있습니다.

관련 문제