Doctrine2 查询(Builder)在使用“where”和“in”子句后失去关系

Posted

技术标签:

【中文标题】Doctrine2 查询(Builder)在使用“where”和“in”子句后失去关系【英文标题】:Doctrine2 query(Builder) loses relations after using "where" and "in" clause 【发布时间】:2015-06-19 22:17:50 【问题描述】:

我有两个实体,我们称它们为“Girl”和“Feature”。实体“Girl”与“Feature”处于单向多对多关系。

我有一个带有简单搜索表单的页面。我想按特征搜索女孩。我在服务器端提交表单后得到的是功能 ID 列表,而我应该返回的是一个女孩列表,这些女孩已选择列出的功能与该女孩具有的所有其他功能。。 p>

让我们看看这个: ╔════════════╦═══════════════╦═══════════════╦═══════════════╗ ║ ║ (1) Feature 1 ║ (2) Feature 2 ║ (3) Feature 3 ║ ╠════════════╬═══════════════╬═══════════════╬═══════════════╣ ║ (1) Girl 1 ║ Yes ║ Yes ║ No ║ ║ (2) Girl 2 ║ Yes ║ No ║ Yes ║ ╚════════════╩═══════════════╩═══════════════╩═══════════════╝

括号中的数字是实体ID。

我首先要做的是:

$qbd = $this->getQbd('AppBundle:Girl', 'g')
        ->select('g, gf')
        ->leftJoin('g.features', 'gf');

从 URL 获取数据(特征 ID)(因为表单使用 GET 方法)并将它们放入 $features 数组后,我执行如下操作:

if (!empty($features)) 
    $qbd->where(
        $qbd->expr()->in('gf.id', ':features')
    )->setParameter('features', $features);

尽可能简单。

一切都很好。几乎。

当我尝试搜索具有特征 id 等于 2 和 3 的女孩时,我得到了两个女孩的结果(这很好)。可悲的是,他们每个人都只有功能 2 和 3(对于这种情况;当我尝试为他们每个人执行 $girl->getFeatures() 时),即使它们都应该包含对功能 1 的引用。

我做错了什么?我已经尝试为这种情况构建其他更复杂的查询,但最后我遇到了同样的问题。

【问题讨论】:

【参考方案1】:

您可以使用“MEMBER OF” DQL 构造。

例如你可以这样做:

$qb->from('AppBundle:Girl', 'g')
   ->select('g')
   ->andWhere(':feature MEMBER OF g.features')
   ->setParameter('feature', $feauture);

它只适用于单一功能的坏事。例如,如果您需要获得具有特征 A 和 B 的女孩,您需要这样做:

$qb->from('AppBundle:Girl', 'g')
   ->select('g')
   ->andWhere(':featureA MEMBER OF g.features')
   ->setParameter('featureA', $featureA)
   ->andWhere(':featureB MEMBER OF g.features')
   ->setParameter('featureB', $featureB);

这是在我知道的集合中搜索某些实体的最干净的方法。但是,如果您需要搜索具有许多相关实体(特征)的某个实体(女孩),使用这种方法您将面临一些性能问题。在这种情况下,使用子查询可能会更好。

【讨论】:

我接受了这个答案,因为它当时为我指明了正确的方向。几年后,我再次偶然发现了类似的问题,您的回答仍然很有帮助。谢谢,Artyom!

以上是关于Doctrine2 查询(Builder)在使用“where”和“in”子句后失去关系的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine Query Builder,“介于”表达式和子查询之间

Doctrine Query Builder,“between”表达式和子查询

在 Doctrine2 查询中使用 Limit 和 Offset

Doctrine2 - 继承映射,查询子类

如何使用Symfony3在Doctrine2 Entity中运行查询查询

如何在 Doctrine2 的查询结果中获取 Collection