查询生成器或调用本身有什么问题


What is wrong in the Query Builder or in the call itself?

我在存储库中有这个功能:

public function buscarConstanciaProducto($solicitudUsuario, $productoSolicitud)
{
    $builder = $this->getEntityManager()->createQueryBuilder();
    $builder->select(array('su', 'p', 'ps', 'c'))
            ->from('AppBundle:SolicitudUsuario', 'su')
            ->leftJoin('su.producto_solicitud', 'ps')
            ->leftJoin('ps.producto', 'p')
            ->leftJoin('su.constancias', 'c')
            ->where('su.id = ?', $solicitudUsuario)
            ->andWhere('ps.id = ?', $productoSolicitud);
    return $builder->getResult();
}

我正试图从我的控制器中调用它,如下所示:

$result = $em->getRepository("AppBundle:Constancia")->buscarConstanciaProducto(
    (int) $request->query->get('id'), // this gets 18
    $productoSolicitud->getId() // this gets 25
);

但我得到了这个错误:

警告:get_class()要求参数1为对象,给定的整数

那里出了什么问题?

这是完整的StackTrace:

[1] Symfony'Component'Debug'Exception'ContextErrorException: Warning: get_class() expects parameter 1 to be object, integer given
    at n/a
        in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 92
    at Symfony'Component'Debug'ErrorHandler->handleError('2', 'get_class() expects parameter 1 to be object, integer given', '/var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php', '92', array('arg' => '18', 'this' => object(Andx)))
        in  line 
    at get_class('18')
        in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 92
    at Doctrine'ORM'Query'Expr'Base->add('18')
        in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 74
    at Doctrine'ORM'Query'Expr'Base->addMultiple(array('su.id = ?', '18'))
        in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base.php line 63
    at Doctrine'ORM'Query'Expr'Base->__construct(array('su.id = ?', '18'))
        in /var/www/html/project.dev/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php line 871
    at Doctrine'ORM'QueryBuilder->where('su.id = ?', '18')
        in /var/www/html/project.dev/src/Sencamer/AppBundle/Entity/Repository/ConstanciaRepository.php line 23
    at AppBundle'Entity'Repository'ConstanciaRepository->buscarConstanciaProducto('18', '25')
        in /var/www/html/project.dev/src/Sencamer/AppBundle/Controller/Comunes/ListadoController.php line 96
    at AppBundle'Controller'Comunes'ListadoController->getConstanciaProductosSolicitudAction(object(Request))
        in  line 
    at ReflectionMethod->invokeArgs(object(ListadoController), array(object(Request)))
        in /var/www/html/project.dev/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php line 63
    at CG'Proxy'MethodInvocation->proceed()
        in /var/www/html/project.dev/vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/Interception/MethodSecurityInterceptor.php line 120
    at JMS'SecurityExtraBundle'Security'Authorization'Interception'MethodSecurityInterceptor->intercept(object(MethodInvocation))
        in /var/www/html/project.dev/vendor/jms/cg/src/CG/Proxy/MethodInvocation.php line 58
    at CG'Proxy'MethodInvocation->proceed()
        in /var/www/html/project.dev/app/cache/dev/jms_diextra/proxies/Sencamer-AppBundle-Controller-Comunes-ListadoController.php line 30
    at EnhancedProxy72c8de70_7ca524686d92d76741252b9b0630ee44b00c6576'__CG__'AppBundle'Controller'Comunes'ListadoController->getConstanciaProductosSolicitudAction(object(Request))
        in  line 
    at call_user_func_array(array(object(ListadoController), 'getConstanciaProductosSolicitudAction'), array(object(Request)))
        in /var/www/html/project.dev/app/bootstrap.php.cache line 3022
    at Symfony'Component'HttpKernel'HttpKernel->handleRaw(object(Request), '1')
        in /var/www/html/project.dev/app/bootstrap.php.cache line 2984
    at Symfony'Component'HttpKernel'HttpKernel->handle(object(Request), '1', true)
        in /var/www/html/project.dev/app/bootstrap.php.cache line 3133
    at Symfony'Component'HttpKernel'DependencyInjection'ContainerAwareHttpKernel->handle(object(Request), '1', true)
        in /var/www/html/project.dev/app/bootstrap.php.cache line 2377
    at Symfony'Component'HttpKernel'Kernel->handle(object(Request))
        in /var/www/html/project.dev/web/app_dev.php line 20

您的问题似乎是,以这种方式使用的where()需要类似于附加表达式的内容。

/**
 * Specifies one or more restrictions to the query result.
 * Replaces any previously specified restrictions, if any.
 *
 * <code>
 *     $qb = $em->createQueryBuilder()
 *         ->select('u')
 *         ->from('User', 'u')
 *         ->where('u.id = ?');
 *
 *     // You can optionally programatically build and/or expressions
 *     $qb = $em->createQueryBuilder();
 *
 *     $or = $qb->expr()->orx();
 *     $or->add($qb->expr()->eq('u.id', 1));
 *     $or->add($qb->expr()->eq('u.id', 2));
 *
 *     $qb->update('User', 'u')
 *         ->set('u.password', md5('password'))
 *         ->where($or);
 * </code>
 *
 * @param mixed $predicates The restriction predicates.
 *
 * @return QueryBuilder This QueryBuilder instance.
 */
 public function where($predicates)
 {
     if ( ! (func_num_args() == 1 && $predicates instanceof Expr'Composite)) {
         $predicates = new Expr'Andx(func_get_args());
     }
     return $this->add('where', $predicates);
}

[来自vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder]

add()方法为

/**
 * @param mixed $arg
 *
 * @return Base
 *
 * @throws 'InvalidArgumentException
 */
public function add($arg)
{
    if ( $arg !== null && (!$arg instanceof self || $arg->count() > 0) )       {
        // If we decide to keep Expr'Base instances, we can use this check
        if ( ! is_string($arg)) {
            $class = get_class($arg);
            if ( ! in_array($class, $this->allowedClasses)) {
                throw new 'InvalidArgumentException("Expression of type '$class' not allowed in this context.");
            }
        }
        $this->parts[] = $arg;
    }
    return $this;
}

[来自vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr/Base]

所以,对我来说,使用where('foo.id', $someVariable);的唯一方法是将表达式作为第二个参数,如下所示

$qb->where('su.id = ?1', $qb->expr()->eq('su.somethingElse', '?2'));

等于

$qb->where('su.id = ?1')
   ->andWhere('su.somethingElse = ?2');

所以,回到这里谈谈你的问题,如果你想设置参数,你应该修改查询的构建过程,如下

public function buscarConstanciaProducto($solicitudUsuario, $productoSolicitud)
{
    $builder = $this->getEntityManager()->createQueryBuilder();
    $builder->select(array('su', 'p', 'ps', 'c'))
            ->from('AppBundle:SolicitudUsuario', 'su')
            ->leftJoin('su.producto_solicitud', 'ps')
            ->leftJoin('ps.producto', 'p')
            ->leftJoin('su.constancias', 'c')
            ->where('su.id = ?1')
            ->andWhere('ps.id = ?2')
            ->setParameter(1, $solicitudUsuario)
            ->setParameter(2, $productoSolicitud)
            ->getQuery() //don't forget this step
    ;
    return $builder->getResult();
}