Symfony One-To-Many,带有连接表查询的单向

时间:2016-09-12 13:50:34

标签: doctrine-orm symfony dql

我在Symfony应用程序中有一些一对多,单向连接表关系,我需要查询,我无法弄清楚如何在DQL或查询生成器中执行此操作。

Like实体本身没有comments属性,因为它可以由许多不同类型的实体拥有。

基本上我需要翻译这样的东西:

SELECT likes
FROM AppBundle:Standard\Like likes
INNER JOIN comment_like ON comment_like.like_id = likes.id
INNER JOIN comments ON comment_like.comment_id = comments.id
WHERE likes.created_by = :user_id
AND likes.active = 1
AND comments.id = :comment_id

我已经尝试了这个,但是连接输出不正确,它选择任何活动的Like,无论它与给定的评论有关联

        $this->createQueryBuilder('l')
        ->select('l')
        ->innerJoin('AppBundle:Standard\Comment', 'c')
        ->where('l.owner = :user')
        ->andWhere('c = :comment')
        ->andWhere('l.active = 1')
        ->setParameter('user', $user)
        ->setParameter('comment', $comment)

2 个答案:

答案 0 :(得分:1)

我看到两个选项来解决这个问题:

  1. 双向关系
  2. 使用SQL(本机查询)+ ResultSetMapping。
  3. 对于最后一个选项,这里是存储库方法的示例(只是检查它是否有效):

    public function getLikes(Comment $comment, $user)
    {
        $sql = '
            SELECT l.id, l.active, l.owner 
            FROM `like` l
            INNER JOIN comment_like ON l.id = comment_like.like_id
            WHERE comment_like.comment_id = :comment_id
                AND l.active = 1
                AND l.owner = :user_id
        ';
        $rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->_em);
        $rsm->addRootEntityFromClassMetadata(Like::class, 'l');
    
        return $this->_em->createNativeQuery($sql, $rsm)
            ->setParameter('comment_id', $comment->getId())
            ->setParameter('user_id', $user)
            ->getResult();
    }
    

    PS:对于Mysql,'like'是保留字。所以,如果一个人希望有一个名字'like'的表 - 只需在定义上用反引号包围名称:

     * @ORM\Table(name="`like`")
    

答案 1 :(得分:0)

我发现Symfony文档在单向查询方面很差。 无论如何,我通过在拥有实体上使用DQL和子选择来实现它,这当然不是那么快。关于如何改进的任何建议都受到欢迎!

$em = $this->getEntityManager();
$query = $em->createQuery('
     SELECT l
     FROM AppBundle:Standard\Like l
     WHERE l.id IN (
         SELECT l2.id
         FROM AppBundle:Standard\Comment c
         JOIN c.likes l2
         WHERE c = :comment
         AND l2.owner = :user
         AND l2.active = 1 
     )'
)
->setParameter('user', $user)
->setParameter('comment', $comment)
;