Symfony Doctrine2:对多对多关系使用querybuilder
为了在系统中搜索人员,我在存储库中编写了一个函数。 此函数接收一个包含字段名和条件的数组,并使用querybuilder生成有效的DQL语句 一切正常,直到我想制定一个搜索规则,如: “查找属于某个域的所有人。” …其中个人和域实体具有多对多关系 根据Symfony2,这种关系定义正确,事实上,一切都在细枝模板和控制器中工作 该函数如下所示:-Symfony Doctrine2:对多对多关系使用querybuilder,symfony,doctrine-orm,repository,query-builder,Symfony,Doctrine Orm,Repository,Query Builder,为了在系统中搜索人员,我在存储库中编写了一个函数。 此函数接收一个包含字段名和条件的数组,并使用querybuilder生成有效的DQL语句 一切正常,直到我想制定一个搜索规则,如: “查找属于某个域的所有人。” …其中个人和域实体具有多对多关系 根据Symfony2,这种关系定义正确,事实上,一切都在细枝模板和控制器中工作 该函数如下所示:- private function query($extra_conditions = null) { $qb = $this->_em-
private function query($extra_conditions = null)
{
$qb = $this->_em->createQueryBuilder();
$query =
$qb->select('p')
->from('AppMainBundle:Person', 'p')
->leftjoin('AppMainBundle:Domain', 'd')
->where("p.firstname IS NOT NULL")
->andWhere("p.lastname IS NOT NULL")
->andWhere("p.function IS NOT NULL");
if ($extra_conditions!=null)
{
foreach ($extra_conditions as $condition)
{
#filter on firstname
if (key($condition)=='firstname')
$query = $query->andWhere('p.firstname LIKE ?1')
->setParameter(1, $condition['firstname']);
#filter on lastname
if (key($condition)=='lastname')
$query = $query->andWhere('p.lastname LIKE ?1')
->setParameter(1, $condition['lastname']);
#filter on gender
if (key($condition)=='gender')
$query = $query->andWhere('p.gender = '.$condition['gender']);
#filter on domain(s)
if (key($condition)=='domains')
$query = $query->andWhere('d.id IN ('.$condition['domains'].')');
#filter on town
if (key($condition)=='town')
$query = $query->andWhere('p.town LIKE ?1')
->setParameter(1, $condition['town']);
}
}
$query = $query->orderBy("p.lastname", "ASC");
$query = $qb->getQuery();
return $query->getResult();
}
没有错误,但任何域都作为搜索条件给出;找到并返回来自所有域的人员
域以类似(2,4)的数组形式提供
我可以做些什么改变来找到属于特定领域的人?经过反复试验,我找到了两个可能的答案: 1)显然,在querybuilder中,您可以引用存在于联接表中的字段,这些字段实际上不是实体的一部分。因此,一种解决办法是:
#filter on domain(s)
if (key($condition)=='domains')
$query = $query->andWhere('p.domain_id IN ('.$condition['domains'].')');
…其中域id位于Symfony2创建的连接表“person\u domain”中,打开引擎盖
2)现在不再需要内部联接。使用内部联接也是可能的,但是它是以错误的方式编写的,无论如何都不会起作用。它应该写为:
->leftjoin('p:domain', 'd', 'ON p.id = d.id')
希望其他人也能从中受益。由于某种原因,我以前无法做到这一点,但现在成功了。我检查了所有我收到的答案,并接受了那些解决问题的答案。谢谢你提醒我,Luiges90。这个答案进一步解释了解决方案2: