2016-10-09 22 views
1

假設我們有兩個實體和它們之間的雙向一對多關聯。在反面,收集可能會變得非常巨大,但大多數時候只需要基於一個固定的標準來確定某個特定的關聯子集。與本機和永久過濾標準的原則一對多關聯

我知道我可以使用chapter 8 of the Doctrine docs中描述的集合和條件或過濾器的額外延遲加載。但是,這隻有在實體經理可以訪問的情況下才有效,但我想要有一個直接在實體級別上工作的解決方案,如Ashley Dawson's blog中所述。

比方說,我們有書籍和章節

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) { /*...*/ } 
} 

現在,​​應該由一個屬性important來加強和Books以下簡單對象模型應該得到第二次集合,只保存重要的章節

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

這是以任何方式可能嗎?我得到的最接近的是在數據庫級別上創建一個SQL視圖important_chapters,它從表chapters中選擇正確的行,然後在Doctrine級別創建一個新的實體ImportantChapter。但是我不喜歡這個解決方法,因爲它表面上創建了第三種類型的實體。當然,可以推進該解決方案並使ImportantChapter爲子類Chapter,使用表繼承並使用important作爲鑑別器列。但是這並不適用於所有情況,特別是如果標準變得比這個玩具例子更復雜。

回答

1

您可以使用標準學說沒有實體管理器也作爲例子:

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

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

希望這有助於

+0

是的,確實如此。然後,我仍然必須弄清楚,如何擴展Criteria類,以便它們支持PostgreSQL的時間和空間擴展。不幸的是,我的標準並不像例子那麼簡單。 – user2690527

+1

我選擇合併您的和我的解決方案。由於Docrine'Criteria'類沒有提供選擇所需的表現力,我在表的頂部創建了一個視圖,該視圖添加了一個帶有布爾類型的附加列 – user2690527