我正在寻找一种方法来扩展我的Symfony2
(我目前使用2.3)Entity
类,并使用一种方法来有效地按需过滤其关系。所以,成像我有两个OneToMany
关系的类:
/**
* ME\MyBundle\Entity\Kindergarten
*/
class Kindergarten
{
/**
* @var integer $id
*/
private $id;
/**
* @var ME\MyBundle\Entity\Kinder
*/
private $kinders;
public function __construct()
{
$this->kinders = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get kinders
*
* @return Doctrine\Common\Collections\Collection
*/
public function getKinders()
{
return $this->kinders;
}
}
/**
* ME\MyBundle\Entity\Kinder
*/
class Kinder
{
/**
* @var integer $id
*/
private $id;
/**
* @var string $name
*/
private $name;
/**
* @var integer $age
*/
private $age;
}
我的目标是在Kindergarten
课程上设置一个方法,以便按需提供所有年龄较大的方法,例如10到12之间:
$myKindergarten->getKindersByAgeInInterval(10,12);
当然,我可以这样做:
class Kindergarten
{
...
public function getKindersByAgeInInterval($start, $end)
{
return $this->getKinders()->filter(
function($kinder) use ($start, $end)
{
$kinderAge = $kinder->getAge();
if($kinderAge < $start || $kinderAge > $end)
{
return false;
}
return true;
}
);
}
...
}
上面的解决方案可行,但效率非常低,因为我需要迭代所有kinder,这可能是一个非常大的列表,无法缓存这些过滤器。我在考虑使用Criteria
类或一些代理模式,但不确定在Symfony2
中做得好的方法,特别是因为它们可能需要访问EntityManager
。
有什么想法吗?
答案 0 :(得分:1)
我建议将此责任提取到EntityRepository
:
<?php
class KinderRepository extends \Doctrine\ORM\EntityRepository
{
public function findByKindergartenAndAge(Kindergarten $entity, $minAge = 10, $maxAge = 20)
{
return $this->createQueryBuilder()
->... // your query logic here
}
}
所有查找都应该在您有权访问实体管理器的类中进行。
这实际上是Doctrine架构所建议的方式。您永远无法访问您实体的任何服务,如果您认为自己需要它,那么您的架构就会出现问题。
当然,如果您以后决定添加更多标准(想象您将按照幼儿园,年龄,体重和身高进行搜索),您可能会觉得存储库方法可能会变得非常难看,请参阅{{3 }})。然后你应该考虑实现更多的逻辑,但同样,这不应该是必要的。