5

我有一个带有子查询的查询:

$query = $this->getEntityManager()->createQueryBuilder();
    $subquery = $query;
    $subquery
        ->select('f.following')
        ->from('ApiBundle:Follow', 'f')
        ->where('f.follower = :follower_id')
        ->setParameter('follower_id', $id)
    ;

    $query
        ->select('c')
        ->from('ApiBundle:Chef', 'c')
        ->where('c.id <> :id')
        ->setParameter('id', $id)
    ;
    $query
        ->andWhere(
            $query->expr()->notIn('c.id', $subquery->getDQL())
        );

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

我得到这个错误:

[Semantical Error] line 0, col 116 near 'f, ApiBundle:Chef': Error: 'f' is already defined.

我找不到错误的原因,别名 f 只定义了一次。有什么建议么?

4

2 回答 2

7

这个问题是关于 PHP 中的对象和引用的。

当您这样做时$subquery = $query;$query作为一个对象,您只需$subquery指向相同的值。

PHP 引用是一个别名,它允许两个不同的变量写入相同的值。从 PHP 5 开始,对象变量不再包含对象本身作为值。它只包含一个对象标识符,允许对象访问者找到实际对象。当一个对象被分配给另一个变量时,不同的变量不是别名:它们持有标识符的副本,它指向同一个对象。

参考:http ://us1.php.net/manual/en/language.oop5.references.php

这意味着在您的代码中,当您编写此代码时:

$subquery
    ->select('f.following')
    ->from('ApiBundle:Follow', 'f')
    ->where('f.follower = :follower_id')
    ->setParameter('follower_id', $id)
;

这相当于:

$query
    ->select('f.following')
    ->from('ApiBundle:Follow', 'f')
    ->where('f.follower = :follower_id')
    ->setParameter('follower_id', $id)
;

所以当你最后打电话时:

$query->andWhere(
        $query->expr()->notIn('c.id', $subquery->getDQL())
    );

您正在使用由 2 个不同变量 ( $query === $subquery) 指向的同一对象的 2 倍。

要解决此问题,您可以使用:

$query = $this->getEntityManager()->createQueryBuilder();
$subquery = $this->getEntityManager()->createQueryBuilder();

或者clone关键字:

$query = $this->getEntityManager()->createQueryBuilder();
$subquery = clone $query;
于 2013-07-31T16:03:02.697 回答
1

我想分享我需要 ORM 映射的解决方案:

以下实体映射如下: 事件 1:M 参与者

Participant class
 /**
 * @ORM\ManyToOne(targetEntity="KKB\TestBundle\Entity\Event", inversedBy="participants")
 * @ORM\JoinColumn(name="event_id", referencedColumnName="id", nullable=false)
 */
private $event;

Event class
/**
 * @ORM\OneToMany(targetEntity="KKB\TestBundle\Entity\Participant", mappedBy="event", cascade={"persist"})
 */
private $participants;


class EventRepository extends \Doctrine\ORM\EntityRepository
{

public function getEventList($userId)
{

    $query = $this->createQueryBuilder('e');
    $subquery = $this->createQueryBuilder('se');

    $subquery
        ->leftJoin('se.participants', 'p')
        ->where('p.user = :userId')
        ;

    return $query->where($query->expr()->notIn('e.id', $subquery->getDQL()))
        ->setParameter('userId', $userId)
        ;
}

}
于 2016-01-02T01:05:24.173 回答