【问题标题】:Doctrine ORM - How to choose the first selected item in select queryDoctrine ORM - 如何在选择查询中选择第一个选定的项目
【发布时间】:2019-11-02 07:51:27
【问题描述】:

我正在使用带有 EasyAdmin 的 Symfony 4,我需要进行一个选择查询来检索所有用户,但我希望选择连接的用户作为第一个结果。

我完全不知道该怎么做。我在想也许在同一个查询中进行多项选择?但我什至不知道该怎么做。

到目前为止,我有这个:

   $repo = $this->getDoctrine()->getRepository(User::class);
   $authUser = $this->getUser();
   $queryBuilder = $repo->createQueryBuilder('u');
   return $queryBuilder;

// 学说 createQueryBuilder 看起来像这样

  public function createQueryBuilder($alias, $indexBy = null)
        {
            return $this->_em->createQueryBuilder()->select($alias)->from($this->_entityName, $alias, $indexBy);
        }

编辑:我必须返回 queryBuilder 对象,而不是结果集,这就是为什么它很棘手。

【问题讨论】:

  • 看看这个stackoverflow.com/questions/34615027/… 使用 CASE 或 UNION。
  • 您的数据库中是否有一个属性表示某人是否已连接?如果是这样,您可以为您的查询构建器添加一个“order by”选项。
  • @ehymel 我需要将经过身份验证的用户的电子邮件与数据库中拥有此电子邮件的用户进行比较
  • 在这种情况下,您将无法仅通过 sql/doctrine 获得答案。您必须在控制器中进行自定义排序后检索,可能使用 php 的 usort

标签: php symfony doctrine-orm


【解决方案1】:

你可以使用 setMaxResults:

    $qb->andWhere('q.start <= :start')
        ->setParameter(':start', $value)
        ->setMaxResults(1)
    ;

【讨论】:

    【解决方案2】:

    一种查询所有用户的方法,但会按照您描述的顺序为您提供一个数组:

    $users = $userRepository->findall();
    foreach ($users as $user) {
        $this->getUser() == $user ? $currentUser[] = $user : $otherUsers[] = $user;
    }
    $myUserList = array_merge($currentUser, $otherUsers);
    

    两个旁注:1:这会查询所有用户,然后将它们拆分。我不确定这是否是你想要的。 2:如果当前没有用户登录,此代码将不起作用,因为不会定义 $currentUser。当然,你可以改变它,让它在没有用户登录的情况下也能工作。

    根据必须返回查询构建器这一事实进行编辑:

    您可以使用CASE 来测试和创建一个属性,您可以在查询中使用AS HIDDEN 将其隐藏,然后按此隐藏属性进行排序,如下所示:

    public function currentUserFirst($userId){
        $qb = $this->createQueryBuilder('u')
            ->select('u, CASE WHEN u.id = :userId THEN 0 ELSE 1 END AS HIDDEN order')
            ->setParameter('userId', $userId)
            ->orderBy('order', 'ASC');
        return $qb;
    }
    

    【讨论】:

    • 谢谢,但我编辑了帖子,确切地说我需要返回 queryBuilder 对象,而不是直接返回结果集,但遗憾的是我不允许修改 queryBuilder 的结果。跨度>
    • @naspy971,我有点认为是这样。确实有点棘手,但有可能。
    • 行得通!哇,我对 SQL 的了解受限于此,非常感谢!
    【解决方案3】:

    正如第一条评论指出的那样,您将需要使用 UNION,而 DQL 不支持该功能。

    因此,您唯一的选择是使用您需要从 EntityManager 获取的 Connection 使用本机查询。

    看起来像这样:

    $id = $this->getUser()->getId();
    $sql = 'SELECT * FROM `users` WHERE `id` = :id UNION SELECT * FROM `users` WHERE`id` != :id'
    $users = $this->getDoctrine()->getConnection()->fetchAll($sql, compact('id'));
    

    【讨论】:

    • 谢谢,但我编辑了帖子,准确地说我需要返回 queryBuilder 对象,而不是直接返回结果集,但遗憾的是我不允许修改 queryBuilder 的结果。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 2018-04-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多