doctrine2查询生成器中的子查询出错

时间:2013-07-31 15:36:37

标签: php symfony doctrine-orm

我有一个子查询的查询:

$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只定义了一次。有什么建议吗?

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

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

以下实体映射如下: 活动1:M参与者

($)                ::   (a -> b) ->   a ->   b
let g=g in (g  $)  ::                 a ->   b
            g      ::   (a -> b)
                                     _____
Functor f =>                        /     \
(<$>)              ::   (a -> b) -> f a -> f b
let g=g in (g <$>) ::               f a -> f b
            g      ::   (a -> b) 
                       ___________________
Applicative f =>      /             /     \
(<*>)              :: f (a -> b) -> f a -> f b
let h=h in (h <*>) ::               f a -> f b
            h      :: f (a -> b)
                             _____________
Monad m =>                  /.------.     \
(=<<)              :: (a -> m b) -> m a -> m b
let k=k in (k =<<) ::               m a -> m b
            k      :: (a -> m b)