Doctrine2 query(Builder) 在使用 "where" 和 "in" 子句后失去关系
Doctrine2 query(Builder) loses relations after using "where" and "in" clause
我有两个实体,我们称它们为 "Girl" 和 "Feature"。实体 "Girl" 与 "Feature".
存在单向多对多关系
我有一个带有简单搜索表单的页面。我想按功能搜索女孩。在服务器端提交表单后,我得到的是一个功能 ID 列表,我应该 return 是一个女孩列表,这些女孩选择了 列出的所有其他功能,那个女孩有 .
让我们看看这个:
╔════════════╦═══════════════╦═══════════════╦═══════════════╗
║ ║ (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 的引用。
我做错了什么?我已经尝试为这种情况构建其他更复杂的查询,但最后我遇到了同样的问题。
您可以使用“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);
据我所知,这是在集合中搜索某个实体的最干净的方法。但是,如果您需要搜索一些具有许多相关实体(特征)的实体(女孩),您将使用这种方法面临一些性能问题。在那种情况下,也许最好使用子查询。
我有两个实体,我们称它们为 "Girl" 和 "Feature"。实体 "Girl" 与 "Feature".
存在单向多对多关系我有一个带有简单搜索表单的页面。我想按功能搜索女孩。在服务器端提交表单后,我得到的是一个功能 ID 列表,我应该 return 是一个女孩列表,这些女孩选择了 列出的所有其他功能,那个女孩有 .
让我们看看这个:
╔════════════╦═══════════════╦═══════════════╦═══════════════╗
║ ║ (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 的引用。
我做错了什么?我已经尝试为这种情况构建其他更复杂的查询,但最后我遇到了同样的问题。
您可以使用“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);
据我所知,这是在集合中搜索某个实体的最干净的方法。但是,如果您需要搜索一些具有许多相关实体(特征)的实体(女孩),您将使用这种方法面临一些性能问题。在那种情况下,也许最好使用子查询。