【问题标题】:Doctrine Query Builder IN clause with multiple values具有多个值的 Doctrine Query Builder IN 子句
【发布时间】:2023-03-12 13:42:02
【问题描述】:

我有一个与 companyType 具有多对多关系的用户实体:

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\CompanyType")
 * @ORM\OrderBy({"name" = "ASC"})
 * @ORM\JoinColumn(nullable=true)
 */
private $companyTypes;

还有一个可以有 0 种或多种类型的 Company 实体:

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\CompanyType", inversedBy="companies")
 * @ORM\OrderBy({"name" = "ASC"})
 * @ORM\JoinColumn(nullable=true)
 */
private $companyTypes;

这会在我的数据库中创建一个 user_companyType 表。

我想用 Doctrine queryBuilder 构建一个查询,如果 u.companyTypes 中的至少一个元素在 c.companyTypes 中,则该查询返回。

我找不到怎么做。

这是我尝试过的:

$userCompanyTypes = array();
foreach ($user->getCompanyTypes() as $companyType) {
    $userCompanyTypes[] = $companyType;
}

$qb = $this->_em->createQueryBuilder('i')
->from(Invoice::class, 'i')
->leftJoin('i.account', 'a')
->leftJoin('i.company', 'c')
->leftJoin('c.companyTypes', 'ct')
->leftJoin('a.users', 'u')
->andWhere("c.companyTypes IN (:userCompanyTypes)") // ... search if there's a match 
->setParameter("userCompanyTypes", $userCompanyTypes);

return $qb->getQuery()->getResult();

长话短说:

  • 一个帐户包含多个用户

  • 发票始终与帐户和公司相关联

  • CompanyType 是一个对象,而不是字符串

  • 我要获取的发票是与用户拥有权限的公司相关联的发票(= 用户拥有公司本身拥有的 companyType)

还有什么我可以与查询生成器一起使用的吗?

【问题讨论】:

  • 试试 $qb->add('where', $qb->expr()->in("c.companyTypes'', $userCompanyTypes));
  • 好吧。 '... some where 子句' 可能没有帮助。你把你的查询压缩得有点太多了,以至于有人帮不上忙。使用实际查询更新问题。继续,如果需要,只需完全删除 []。但是给我们一个真实的查询并验证 $userCompanyTypes 是一个数组。
  • @Albeis 不需要使用 expr。假设查询的其余部分是正确的,问题中显示的 andWhere 子句将正常工作。
  • 然后等待完整的查询!
  • 我用更多信息更新了查询,感谢您的帮助!

标签: php symfony doctrine


【解决方案1】:

我通常不喜欢在没有设置测试用例的情况下回答这类问题。你的错误信息有点奇怪,但我会试一试。我知道 IN 子句适用于个人 ID。所以也许:

$userCompanyTypeIds = array();
foreach ($user->getCompanyTypes() as $companyType) {
    $userCompanyTypeIds[] = $companyType->getId();
}
$qb = $this->_em->createQueryBuilder('i')
->select('count(DISTINCT i.id)')
->from(Invoice::class, 'i')
->leftJoin('i.account', 'a')
->leftJoin('i.company', 'c')
->leftJoin('c.companyTypes', 'ct')
->leftJoin('a.users', 'u')
->andWhere("ct.id IN (:userCompanyTypeIds)") // ... search if there's a match 
->setParameter("userCompanyTypeIds", $userCompanyTypeIds);

$count = $qb->getQuery()->getSingleScalarResult();

至少应该让你更进一步。更新了显示如何获得总计数的答案。从来都不是使用 expr 类的忠实粉丝,尽管它很常见。

【讨论】:

  • 我可以在我的代码中看到进度,这一切都是有道理的,但是:假设我想计算我的结果,我添加了 $qb->select($qb->expr()->count ('distinct(i.id)')); --- 如果没有最后一个 andWhere 和 setParameter,我会得到一个有效的查询。有了它,在我的错误日志中,我看到“SELECT FROM”(SELECT 之后没有任何内容)
  • 用计数语法更新了答案。
  • 它终于在最后一次更新中工作了!感谢您的帮助@Cerad :)
猜你喜欢
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多