【问题标题】:Doctrine - DQL - How to query a query result?Doctrine - DQL - 如何查询查询结果?
【发布时间】:2017-03-02 09:12:27
【问题描述】:

我没有找到如何查询(使用 DQL)第一个 DQL 查询的结果。

我有第一个 DQL 查询,例如:

$query = $this->createQueryBuilder('q')
$query->[methods()]
$query->->getQuery()->getResult();

从这个查询结果我想做另一个 DQL 查询。但是getResult方法返回一个数组。

获得的完美解决方案是对第一个查询的结果执行另一个 DQL 查询。有什么解决办法吗?

编辑:我正在查询存储库文件(“[Entity]Repository.php”)。从我的第一个 Doctrine 查询中,我期望得到第一个结果。从这个结果中,我想执行另一个选择查询。
换句话说,我想知道如何将我的第一个查询的结果“转换”到一个“临时”表中,我将从该表中执行另一个 Doctrine 查询。

【问题讨论】:

    标签: symfony doctrine-orm


    【解决方案1】:

    如果您需要使用另一个查询的结果进行查询,您可以使用子查询。例如:

    $qb  = $this->createQueryBuilder('qb')->where('r.name = :name')->setParameter('name', $name);
    $qb2 = $this->createQueryBuilder('qb2');
    
    $qb->andWhere(
        $qb->expr()->in(
            'r.id',
            $qb2->select('u.id')
                ->from('AppBundle:User', 'user')
                ->getQuery()->getDQL()
        )
    );
    

    【讨论】:

    • 感谢您的回答。这没有回应最初的问题。结果我更新了这个问题。
    • 感谢您的回答。这没有回应最初的问题。结果我更新了这个问题。你建议做一个子查询: select 'values' from 'table' where 'value' in another select 我想知道如何在第一个查询的结果中进行选择(例如将第一个结果转换为临时表)
    • 你想做这样的事情吗? SELECT * FROM table WHERE id IN (1, 2, 3, 4);
    • No :-) 我想做类似的事情:“(SELECT * FROM table WHERE conditions)AS tmp”然后“SELECT * FROM tmp WHERE conditions”
    • 我不确定 Doctrine 是否提供此功能。我认为您可以通过子查询或在新查询中设置结果数组来获得此行为,例如: $qb->andWhere(YOUR_NEW_CONDITIONS)->andWhere($qb->expr()->in ('r.id', $resultArrayIdList))。
    【解决方案2】:

    你不能完全按照你的想法去做。 Doctrine 在 RDBM 中为每个查询创建临时表或其他工件是很愚蠢的。

    也就是说,您的用例并不完全是疯狂的;我可以想象一个用例,您需要一个初始的“宽”结果集,然后是一个更窄的子集。

    我可以想到两种方法来解决这个问题:

    1. 利用单个 QueryBuilder 实例依次执行两个查询,同时添加其他条件。

    2. 将 getResult() 中的数组包装在 ArrayCollection 中,并使用 criteria API 过滤集合。条件 API 无法完成原始 DQL 查询所能做的所有事情,但它非常强大。

    我将从标准 API 开始。过滤发生在内存中,避免了到数据库的另一次往返,以及(通常更重要的)一堆水化开销。

    【讨论】:

      【解决方案3】:

      这听起来像是您希望使用 Doctrine 的 DTO 功能。它允许您创建从单个实体或多个实体收集的不同值构建的数据传输对象。 "NEW" Operator Syntax

      如果您只想检索单个结果并且不想遍历多个结果,可以使用getOneOrNullResult() 方法。

      $query = $this->createQueryBuilder('q');
      ...
      $query->select('NEW MyDTO(q.id, q.name, q1.id)');
      $dto = $query->->getQuery()->getOneOrNullResult();
      

      返回的 DTO 将包含从您想要获取的各种表中检索到的原始值。

      要记住的重要一点是 Doctrine ORM 处理实体。它不只返回几个选定的字段。您可以使用partials 选择特定字段,但强烈建议不要使用它们。首选使用 DTO,因为它们不会被缓存并提供更好的运输工具。

      【讨论】:

        猜你喜欢
        • 2013-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-21
        • 1970-01-01
        • 2021-08-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多