2016-10-09 5 views
1

2つのエンティティーとそれらの間に双方向1対多の関連があるとします。反対側では、コレクションは本当に巨大になることがありますが、ほとんどの場合、固定基準に基づいて関連の特定のサブセットのみが必要です。ネイティブおよびパーマネントフィルター基準とのDoctrine 1対多の関連

chapter 8 of the Doctrine docsに記載されているように、コレクションと基準またはフィルタの余分な読み込みを使用できることはわかっています。ただし、これはエンティティマネージャがアクセス可能な場合にのみ機能しますが、Ashley Dawson's blogで説明したエンティティレベルで直接動作するソリューションをご希望です。

唯一の重要な章

を格納する第2のコレクションを取得する必要があり、我々は本や章今

class Book { 
    /** 
    * @ORM\OneToMany(targetEntity = "Chapter", mappedBy = "book") 
    * @var ArrayCollection 
    */ 
    protected $chapters; 

    /** 
    * @return Chapter[] 
    */ 
    public function getChapters() { /*...*/ } 

    /** 
    * @param Chapter $chapter 
    */ 
    public function addChapter(Chapter $chapter) { /*...*/ } 

    /** 
    * @param Chapter $chapter 
    */ 
    public function removeChapter(Chapter $chapter) { /*...*/ } 
} 

class Chapter { 
    /** 
    * @ORM\ManyToOne(targetEntity = "Book", inversedBy = "chapters") 
    * @ORM\JoinColumn(name = "book_id", referencedColumnName="id") 
    * @var Book|null 
    */ 
    protected $book; 

    /** 
    * @return Book|null 
    */ 
    public function getBook() { /*...*/ } 

    /** 
    * @param Book|null $newBook 
    */ 
    public function setBook(Book $newBook = null) { /*...*/ } 
} 

と次のような単純なオブジェクトモデルを持って、​​は属性importantBooksにより増強されなければならない、のは、言ってみましょう

class Book { 
    // ... as above ... 

    /** 
    * @ORM\OneToMany(targetEntity = "Chapter", mappedBy = "book") 
    * **HERE WE NEED TO SPECIFY SOME CRITERION FOR chapter.important = true** 
    * @var ArrayCollection 
    */ 
    protected $importantChapters; 

    /** 
    * @return Chapter[] 
    */ 
    public function getImportantChapters() { 
    return $this->importantChapters->toArray(); 
    } 
} 

class Chapter { 
    // ... as above ... 

    /** 
    * @Column(type="boolean") 
    * @var boolean 
    */ 
    protected $important; 
} 

これはどのような方法でも可能ですか?私が得た最も近いのは、テーブルchaptersから正しい行を選択し、Doctrineレベルで新しいエンティティImportantChapterを作成するデータベースレベルのSQLビューimportant_chaptersを作成することでした。しかし、私は、この回避策を嫌うのは表面的に第3のタイプのエンティティを作成するためです。もちろん、その解決策を推進して、の子クラスをChapterとし、テーブルの継承を使用して、importantを識別子の列として使用できます。しかし、これはすべてのケースで機能しません。特に、この玩具の例よりも基準が複雑になる場合は特にそうです。

答えて

1

あなたは一例として、また、エンティティマネージャなしでDoctrineの基準を使用することができます。

/** 
    * @return Chapter[] 
    */ 
    public function getImportantChapters() { 
    $criteria = Criteria::create(); 
    $criteria->where(Criteria::expr()->eq('important', true)); 

    return $this->chapters->matching($criteria); 
    } 

・ホープ、このヘルプ

+0

はい、確かに。それでは、PostgreSQLの時間的および空間的拡張をサポートするようにCriteriaクラスを拡張する方法を理解しなければなりません。残念ながら、私の基準は例のように単純ではありません。 – user2690527

+1

あなたと私のソリューションを組み合わせることを選択しました。 Docrineの 'Criteria'クラスは選択に必要な表現力を提供していないので、テーブルの上にブール型の追加の列を追加するビューを作成しました – user2690527

関連する問題