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

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
);

但是我得到这个错误:

Warning: get_class() expects parameter 1 to be object, integer given

哪里出了问题?

这是完整的 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(),以这种方式使用,需要类似 additional 表达式。

/**
 * 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();
}