社区您好!
我在 Doctrine ORM 查询中遇到了一个具有挑战性的问题,该查询与根据我的帐户和联系人实体查找用户联系人相关。让我提供一些背景信息:
实体结构:
联系单位:
/**
* @ORM\ManyToOne(targetEntity=Account::class, inversedBy="contacts")
* @ORM\JoinColumn(nullable=false)
*/
private $Account_source;
/**
* @ORM\ManyToOne(targetEntity=Account::class, inversedBy="contacts_backward")
* @ORM\JoinColumn(nullable=false)
*/
private $Account_Targets;
账户实体:
/**
* @ORM\OneToMany(targetEntity=Contact::class, mappedBy="Account_source", orphanRemoval=true)
*/
private $contacts;
/**
* @ORM\OneToMany(targetEntity=Contact::class, mappedBy="Account_Targets", orphanRemoval=true)
*/
private $contacts_backward;
问题描述:
我正在尝试编写一个 Doctrine ORM 查询,它允许我查找给定用户 ($searcherId) 的用户联系人,其中该用户可以是联系人关系中的 Account_source 或 Account_Targets。目标是在关系的两个方向上找到联系人。
初始查询:
最初,我编写了以下查询,该查询仅查找关系的一个方向上的联系人,其中登录用户是 Account_Target:
public function searchByName($value, $searcherId)
{
return $this->createQueryBuilder('a')
->select('a.firstName as firstname', 'a.lastName as lastname', 'a.username as username', 'a.id as id')
->leftJoin('a.contacts', 'c')
->where('c.Account_source = :id AND a.id = c.Account_Targets')
->andWhere('(a.username like :val OR a.firstName like :val OR a.lastName like :val)')
->setParameter('val', '%' . $value . '%')
->setParameter('id', $searcherId)
->orderBy('a.firstName', 'ASC')
->getQuery()
->getResult();
}
问题:
初始查询用于在用户登录的一个方向查找联系人,即 Account_Target。但是,它没有涵盖登录用户也可能是 Account_source 的场景。
例如,Ostwind(目标)可以找到Skorpiono(源),但Skorpiono(源)也只能找到Skorpiono(源)
尝试的解决方案:
为了解决此限制,我修改了查询以包含关系的两个方向,如下所示:
// The modified query that attempted to find contacts in both directions
public function searchByName($value, $searcherId)
{
return $this->createQueryBuilder('a')
->select('a.firstName as firstname', 'a.lastName as lastname', 'a.username as username', 'a.id as id')
->leftJoin('a.contacts', 'c')
->leftJoin('a.contacts_backward', 'cb')
->where('(c.Account_source = :id AND a.id = c.Account_Targets) OR (cb.Account_Targets = :id AND a.id = cb.Account_source)')
->andWhere('(a.username like :val OR a.firstName like :val OR a.lastName like :val)')
->setParameter('val', '%' . $value . '%')
->setParameter('id', $searcherId)
->orderBy('a.firstName', 'ASC')
->getQuery()
->getResult();
}
当前问题:
现在,当前的问题是修改后的查询没有返回任何结果,并且我无法找到关系任一方向的联系人。
额外要求:
在以后的帮助中,我还想实现一个在查询中排除搜索自己的功能。
我将非常感谢任何有关如何修改查询或实体结构以实现双向查找用户联系人的目标的见解或建议。谢谢您的协助!
我找到答案了,是UNION
SELECT
a0_.first_name AS first_name,
a0_.last_name AS last_name,
a0_.username AS username,
a0_.id AS id
FROM
contact c2_
LEFT JOIN account a0_ ON c2_.account_source_id = a0_.id
WHERE
c2_.account_targets_id = :id
AND (a0_.first_name LIKE :val OR a0_.last_name LIKE :val OR a0_.username LIKE :val)
UNION
SELECT
a1_.first_name AS first_name,
a1_.last_name AS last_name,
a1_.username AS username,
a1_.id AS id
FROM
contact c2_
LEFT JOIN account a1_ ON c2_.account_targets_id = a1_.id
WHERE
c2_.account_source_id = :id
AND (a1_.first_name LIKE :val OR a1_.last_name LIKE :val OR a1_.username LIKE :val)