使用表达式生成器在OR内嵌入条件数的AND语句

时间:2016-05-31 22:02:07

标签: php doctrine-orm

所需查询包括where语句,其中包含基本帐户要求以及任何可能的用户选择,其数据为一对。下面的代码不适用于多个选择,即else {}不正确。有没有办法有条件地在andWhere里面的orX里面构建andX?

    $queryBuilder
        ...
        ->where(
            $queryBuilder->expr()->andX(
                $queryBuilder->expr()->eq('t.code', $queryBuilder->createPositionalParameter($this->code)),
                $queryBuilder->expr()->neq('det.completed', '1')
            )
        );

    if (count($selected) == 0) {
        // no results returned
    }
    else if (count($selected) == 1) {
        $queryBuilder->andWhere('det.co_id=' . $queryBuilder->createPositionalParameter($co_array[0]) . ' AND det.ct_id=' . $queryBuilder->createPositionalParameter($ct_array[0]));
    }
    else {
        $nestedWhere = $this->db->createQueryBuilder();
        for ($i=0; $i < count($selected); $i++) {
            $nestedWhere->expr()->orX(
                $nestedWhere->expr()->andX(
                    $nestedWhere->expr()->eq('det.co_id', $nestedWhere->createPositionalParameter($co_array[$i])),
                    $nestedWhere->expr()->eq('det.ct_id', $nestedWhere->createPositionalParameter($ct_array[$i]))
                )
            );
        }
        $queryBuilder->andWhere($nestedWhere->expr()); // need dynamic list of orX here
    }

1 个答案:

答案 0 :(得分:0)

我找到了CompositeExpression类,我的问题似乎是它的确切目的。我的解决方案代码和Doctrine文档的链接如下。

http://www.doctrine-project.org/api/dbal/2.3/class-Doctrine.DBAL.Query.Expression.CompositeExpression.html

// replacing the else {} in thequestion above
else {
    $orX = new CompositeExpression(CompositeExpression::TYPE_OR);

    for ($i=0; $i < count($selected); $i++) {
        $andX = new CompositeExpression(CompositeExpression::TYPE_AND);
        $andX->add('det.co_id = :co' . (string)$i);
        $andX->add('det.ct_id = :ct' . (string)$i);
        $orX->add($andX);
        $queryBuilder
            ->setParameter("co{$i}", $co_array[$i])
            ->setParameter("ct{$i}", $ct_array[$i]);
    }
    $queryBuilder->andWhere($orX);
}