哪些陈述没有附加

时间:2011-05-12 22:28:49

标签: doctrine doctrine-orm

我正在尝试动态构建查询。它的初始状态很好。这是应在每个查询中出现的初始where子句

$qb->add('where', $qb->expr()->andx(
    $qb->expr()->eq('s.competitor', $competitor),
    $qb->expr()->eq('s.ignored', $ignored),
    $qb->expr()->eq('s.id', $params['s_id']),
    $qb->expr()->eq('s.id', 'k.targetSite')
), true);

但我正在构建的应用程序允许用户进行过滤。当发生这种情况时,我想在查询构建器中添加其他where子句。当此行稍后在代码中执行时,它将覆盖上面的where语句。

$qb->add('where',  $qb->expr()->like($col, $val), true );

根据我的阅读,第3个参数$append应保留以前的陈述,但这并没有发生。在Doctrine 1.2中,我可以做这样的事情:

foreach($filter as $col => $val) {
    $dql->addWhere($col = ?, array($val));
}

如何动态地向where QueryBuilder添加where子句?

更新

这是一份完整的陈述

$where = array('col' => 'k.text', 'val' => 'some word%');

$qb = $this->entityManager->createQueryBuilder()
    ->select('s, sc')
    ->from('Dashboard\Entity\Section', 'sc')
    ->innerJoin('sc.keyword', 'k')
    ->innerJoin('sc.site', 's')
    ->leftJoin('k.keywordCategory', 'kc')
    ->leftJoin('k.keywordSubCategory', 'ksc');

$qb->add('where', $qb->expr()->andx(
    $qb->expr()->eq('s.competitor', $competitor),
    $qb->expr()->eq('s.ignored', $ignored),
    $qb->expr()->eq('s.id', $params['s_id']),
    $qb->expr()->eq('s.id', 'k.targetSite')
), true);

if ($where) {
    $qb->add('where', $qb->expr()->andx(
             $qb->expr()->like($where['col'], $where['val'])
    ), true);
}

$qb->addGroupBy('k.id');
    $qb->addGroupBy('s.id');

$qb->setFirstResult( $params['start'] )
   ->setMaxResults( $params['limit'] );

$q = $qb->getQuery();
echo $q->getSql();

输出

SELECT s0_.id AS id0, k1_.id AS id1, k1_.name AS name2, k2_.id AS id3, k2_.name AS   name4, k3_.id AS id5, k3_.text AS text6, k3_.search_vol AS search_vol7, s4_.id AS id8, s4_.sub_domain AS sub_domain9, MIN(s0_.rank) AS sclr10, MAX(s0_.created) AS sclr11 
FROM section s0_ 
INNER JOIN keyword k3_ ON s0_.k_id = k3_.id 
INNER JOIN site s4_ ON s0_.s_id = s4_.id 
LEFT JOIN keyword_category k1_ ON k3_.k_cat_id = k1_.id 
LEFT JOIN keyword_sub_category k2_ ON k3_.k_subcat_id = k2_.id 
WHERE k3_.text LIKE 'some word%' 
GROUP BY k3_.id, s4_.id LIMIT 25 OFFSET 0

如果我没有添加if ($where)子句,那么第一个andx where语句仍然存在。但是当我尝试动态添加它们时,只添加了最后的WHERE语句,清除了所有其他语句。我还应补充一点,我也是这样尝试的。

if ($where) {
    $qb->add('where', $qb->expr()->like($where['col'], $where['val']), true);
}

我可以成功使用

$qb->andWhere( $qb->expr()->like($where['col'], $where['val']) );

但是,查询生成器的API文档说明我尝试使用它的方式也应该是有效的。想要确保我做得对,或者这是一个错误。

2 个答案:

答案 0 :(得分:3)

Looking at the code,看起来你正在尝试做的事情是行不通的,不过,无论是在任何地方记录还是仅仅是一个错误都是值得怀疑的,我认为。

add()中,如果零件已作为数组存储在查询构建器中,则传入的DQL部分似乎只会附加:

   $isMultiple = is_array($this->_dqlParts[$dqlPartName]);
   ...

    if ($append && $isMultiple) {
        if (is_array($dqlPart)) {
            $key = key($dqlPart);

            $this->_dqlParts[$dqlPartName][$key][] = $dqlPart[$key];
        } else {
            $this->_dqlParts[$dqlPartName][] = $dqlPart;
        }
    } else {
        $this->_dqlParts[$dqlPartName] = ($isMultiple) ? array($dqlPart) : $dqlPart;
    }

与大多数其他DQL部分不同,WHERE子句未初始化为数组:

private $_dqlParts = array(
    'select'  => array(),
    'from'    => array(),
    'join'    => array(),
    'set'     => array(),
    'where'   => null,
    'groupBy' => array(),
    'having'  => null,
    'orderBy' => array()
);

现在,这看起来有点像它的设计,但是Doctrine 2相当新,而且这一点似乎最近在不断发展。就个人而言,我会针对这种行为提出一个错误,看看项目人们说了些什么。如果不出意外,您最终可能会得到改进的文档......

答案 1 :(得分:3)

您可以正常使用 - > andWhere()(它也可以修复您的问题)。

Doctrine 2 QueryBuilder是一个相当创新的概念(因为它混合了程序化和流畅的样式),并且可能存在与之相关的错误。

您应该在代码中注意到的一点:您应该考虑编程,而不是使用 - > add('where',...)。向andX()对象添加更多项目,最后将关联添加到 - > add('where',...)(甚至更好: - > where(...))