假设我们有两个实体并且它们之间存在双向一对多关联。在反面,集合可以变得非常庞大,但大多数时候只需要基于固定标准的关联的某个特定子集。
我知道我可以按照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 ) { /*...*/ }
}
现在,Chapters
应该通过属性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
作为鉴别器列。但这并不适用于所有情况,特别是如果标准变得比这个玩具示例更复杂。
答案 0 :(得分:1)
您也可以在没有实体管理器的情况下使用Doctrine Criteria,例如:
/**
* @return Chapter[]
*/
public function getImportantChapters() {
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('important', true));
return $this->chapters->matching($criteria);
}
希望这个帮助