如何构建动态学说查询?

How to build a dynamic doctrine query?

我正在尝试构建一个动态学说查询。当我这样尝试时,它起作用了

    $qb->andWhere($qb->expr()->orX(
        $qb->expr()->andX(
            $qb->expr()->eq('t.width', '245'),
            $qb->expr()->eq('t.height', '45'),
        ),
        $qb->expr()->andX(
            $qb->expr()->eq('t.width', '225'),
            $qb->expr()->eq('t.height', '65'),
        )
    ));

但我会从数组中传递键和值。

我的数组如下所示:

[
  0 => [
    "width" => "245"
    "height" => "45"
  ]
  1 => [
    "width" => "225"
    "height" => "65"
  ]
]

现在,我尝试了以下代码。

    $conditions = $qb->expr()->orX(
        $qb->expr()->andX()
    );

    foreach ($wheres as $outerKey => $outerValue) {
        foreach ($outerValue as $innerKey => $innerValue) {
            $conditions->add("te.$innerKey = :innerValue");
            $qb->setParameter('innerValue', $innerValue);
        }
    }
    $qb->andWhere($conditions);

    dd($qb->getDQL());

但是返回的 SQL 与我尝试使用静态值时不一样。

所以你可以通过两种方式(我能想到的)来做到这一点。首先,使用上面显示的表达式,但带有额外的私有函数:

private function getExpressions(QueryBuilder $qb, array $fields)
{
    $andX = $qb->expr()->andX();
    foreach ($fields as $field => $value) {
        $andX->add($qb->expr()->eq('t.' . $field, $value));
    }

    return $andX;
}

public function getDQL($conditions)
{
    $qb = $this->createQueryBuilder('t');

    $orX = $qb->expr()->orX();
    foreach ($conditions as $i => $fields) {
        $orX->add($this->getExpressions($qb, $fields));
    }
    $qb->add('where', $orX);

    dump($qb->getDQL());
    exit;
}

对我来说,弄清楚这个问题有点费时间。我实际上用上面提到的方式(手动构建 where 子句)做得更快:

$i = 0;
foreach ($conditions as $fields) {
    $j = 0;
    foreach ($fields as $field => $value){
        $whereStr .= " " . $field . " = " . $value;
        $j++;
        if ($j < count($fields)){
            $whereStr .= " AND";
        }
    }
    
    $i++;
    if ($i < count($conditions)){
        $whereStr .= " OR";
    }
}

如果我正确理解您的逻辑,这应该可行。如果我误解了您的要求,您可以切换 orX/andX 表达式。