首页 > 解决方案 > Doctrine - 从没有根实体的多对多关系中检索集合

问题描述

我有 2 个实体,比如说

class A
{
...
    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="B")
     * @ORM\JoinTable(name="a_b",
     *      joinColumns={@ORM\JoinColumn(name="a_id", referencedColumnName="id", onDelete="CASCADE")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="b_id", referencedColumnName="id", onDelete="CASCADE")}
     * )
     */
    protected $bs;
...
    /**
     * @return ArrayCollection
     */
    function getBs()
    {
        return $this->bs;
    }
...
}

class B
{
...
}

具有仅在一侧定义的多对多关系 (A)。

我想要实现的是使用 Doctrine 的查询构建器获取与单个任意 A 实体相关的 B 实体集合。我被限制只能使用查询生成器来做,做类似$a->getBs()的事情不是一种选择。与原生 sql 相同,定义双方的关系或使用存储库,这是不可能的。

预期的结果应该类似于

[
    B {},
    B {},
]

我假设像

$em = $container->get('doctrine');
$qb = $em->createQueryBuilder();

$qb->select('b')
    ->from(A::class, 'a')
    ->join('a.bs', 'b')
    ->where($qb->expr()->eq('a', ':entity'))
    ->setParameters(['entity' => 1]);

$res = $qb->getQuery()->getResult();

会工作。

唉,这会引发错误Cannot select entity through identification variables without choosing at least one root entity alias.

尝试过类似的东西,$qb->select('a.bs')但那个也会引发错误Invalid PathExpression. Must be a StateFieldPathExpression.

我确实有一个解决方案(见下文),但它真的很难看,所以我希望有人有更好的解决方案。

$qb->select('b')
    ->from(A::class, 'a')
    ->join('a.bs', 'ab')
    ->join(B::class, 'b', Join::WITH, $qb->expr()->eq('ab.id', 'b.id'))

如果有人可以提供一些建议,我将不胜感激。

标签: symfonydoctrinequery-builder

解决方案


在这种情况下,根实体是 A - 它必须在 select 方法中。你可以尝试这样的事情:

$qb = $em->createQueryBuilder();

$qb->select('a, bs')
    ->from(A::class, 'a')
    ->leftJoin('a.bs', 'bs')
    ->where('a.id = :id')
    ->setParameter('id', 1)
;

$entityA = $qb->getQuery()->getOneOrNullResult();
$entityA->getBs(); // Returns all bs from entity A with id 1

推荐阅读