【问题标题】:How to get previous and next entity through entity manager如何通过实体管理器获取上一个和下一个实体
【发布时间】:2016-05-02 12:51:29
【问题描述】:

这就是我能够使用它的 id 获取用户实体的方式:

$userEntity = $em->getRepository('ModelBundle:User')->find($userId);

有没有办法根据这个 $userEntity 获取上一个和下一个实体?

例如:我获取了 $userEntity 并且它的 id 是 100,现在我想获取以前的实体,而不管它的 id 是 99、80、70 是什么!与下一个实体的情况相同..

我已经可以使用一些 PHP hack 获取下一个和上一个,但是我正在寻找更好的方法..

已编辑: 只是为了澄清我正在寻找面向对象的方法,如下所示:

$userEntity = $em->getRepository('ModelBundle:User')->find($userId);
$previousUserEntity = $userEntity->previous(); //example
$previousUserEntity = $userEntity->next(); //example

我知道 userEntity 不包含任何像 previous() 和 next() 这样的方法,这只是一个示例,如果存在可以帮助以面向对象的方式直接获取下一个和上一个实体的方法!

【问题讨论】:

  • $previousUserEntity = $userEntity->previous(); 这需要在您的实体中注入实体管理器,不建议这样做。如果你想这样做,你会在这里找到解决方案:stackoverflow.com/a/15556566/2257664stackoverflow.com/q/14684745/2257664
  • 确实,我无法在任何地方找到它,所以我必须接受您的回答,因为我使用它而不是我的 :) 谢谢,
  • 不客气,就像我链接的答案中写的那样,将实体和数据库逻辑分开会更干净。感谢您更正我的回答!

标签: symfony doctrine-orm doctrine


【解决方案1】:

将此功能添加到您的存储库类

public function previous(User $user)
{
    return $this->getEntityManager()
        ->createQuery(
            'SELECT u
            FROM ModelBundle:User u
            WHERE u.id = (SELECT MAX(us.id) FROM ModelBundle:User us WHERE us.id < :id )'
        )
        ->setParameter(':id', $user->getId())
        ->getOneOrNullResult();
}

public function next(User $user)
{
    return $this->getEntityManager()
        ->createQuery(
            'SELECT u
            FROM ModelBundle:User u
            WHERE u.id = (SELECT MIN(us.id) FROM ModelBundle:User us WHERE us.id > :id )'
        )
        ->setParameter(':id', $user->getId())
        ->getOneOrNullResult();
}

【讨论】:

  • 感谢丹尼斯的回复,我正在寻找任何 OO 解决方案,可能是通过教义2?
  • @MuzafarAli OO 解决方案是什么意思?这个解决方案使用dql,所以是通过doctrine2
  • 他可能的意思是他想使用实体实例的方法访问下一个和上一个对象,但我认为不可能
【解决方案2】:

可以通过搜索值大于或小于给定值的所有记录,对它们进行排序,然后只取第一个或最后一个结果来获取上一个和下一个记录。

假设我们有这些 id:

70
80
99
100

为了得到99之前的用户,我们想要id小于99的last用户。这是在custom repository 中添加此代码的代码:

public function getPreviousUser($userId)
{
    $qb = $this->createQueryBuilder('u')
        ->select('u')

        // Filter users.
        ->where('u.id < :userId')
        ->setParameter(':userId', $userId)

        // Order by id.
        ->orderBy('u.id', 'DESC')

        // Get the first record.
        ->setFirstResult(0)
        ->setMaxResults(1)
    ;

    $result = $qb->getQuery()->getOneOrNullResult();
}

在控制器中:

$em->getRepository('ModelBundle:User')->getPreviousUser($userId);

这将返回 ID 为 80 的记录。


为了得到99之后的用户,我们想要id大于99的第一个用户:

public function getNextUser($userId)
{
    $qb = $this->createQueryBuilder('u')
        ->select('u')

        ->where('u.id > :userId')
        ->setParameter(':userId', $userId)

        ->orderBy('u.id', 'ASC')

        ->setFirstResult(0)
        ->setMaxResults(1)
    ;

    $result = $qb->getQuery()->getOneOrNullResult();
}

在控制器中:

$em->getRepository('ModelBundle:User')->getNextUser($userId);

这将返回 ID 为 100 的记录。

【讨论】:

  • 感谢 A.L,根据我的第一条评论,我正在通过 Doctrine2 寻找任何 OO 解决方案..
  • @MuzafarAli 对不起,我不明白你的问题,你的意思是你不想使用存储库吗?
  • 不,我说的是面向对象的方法..例如在一对多中我可以这样做“$groupEntity->getUsers()->first()”,以这种方式我能够获得第一条记录..
  • @MuzafarAli 很抱歉,但我不明白。您能否在您的问题中添加预期代码的示例?
  • 很好的答案。如果你也可以实现这个普通的 MySQL 解决方案,你就是一个伟大的英雄,在一个查询中获得两个“邻居”:stackoverflow.com/a/15992856/1405981
猜你喜欢
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
相关资源
最近更新 更多