【问题标题】:doctrine get count with criteria on a many-to-many self-referencing relation学说在多对多自引用关系上被计算在内
【发布时间】:2012-12-14 10:21:43
【问题描述】:

我有一个可以有很多朋友的用户。表示关系是自引用的。 我现在需要根据他们的性别计算我朋友的朋友数。到目前为止,我想出了以下解决方案。

我的用户实体:

<?php

namespace Acme\UserBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="Acme\UserBundle\Entity\Repository\UserRepository")
 * @ORM\Table(name="users")
 */
class User extends BaseUser
{

    /**
     * @ORM\ManyToMany(targetEntity="Acme\UserBundle\Entity\User", inversedBy="friendsOf")
     * @ORM\JoinTable(name="map_user_friend",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="friend_id", referencedColumnName="id")}
     *      )
     */
    protected $friends;

    /**
     * @ORM\ManyToMany(targetEntity="Acme\UserBundle\Entity\User", mappedBy="friends")
     */
    private $friendsOf;


    /**
     * @ORM\Column(type="string", length=1, nullable=true)
     */
    protected $gender;

    // other fields ...

}

我的 UserRepository 有以下方法:

public function getFriendsQuery(User $user)
{
    return $this->getEntityManager()->createQueryBuilder()
        ->select('u as user, COUNT(DISTINCT mf.id) as male_friends, COUNT(DISTINCT ff.id) as female_friends')
        ->from('Oneup\UserBundle\Entity\User', 'u')
        ->leftJoin('u.friendsOf', 'f')
        ->leftJoin('u.friendsOf', 'mf', 'with', 'mf.gender = :gender')->setParameter('gender', 'm')
        ->leftJoin('u.friendsOf', 'ff', 'with', 'ff.gender = :gender')->setParameter('gender', 'w')
        ->where('f = :user')->setParameter('user', $user)
        ->groupBy('u.id')
    ;
}

在控制器中,我现在首先通过Doctrine\Common\Util\Debug::dump($qb-&gt;getQuery()-&gt;getSQL()); 转储 SQL,然后返回

SELECT u0_.username AS username0,
       u0_.username_canonical AS username_canonical1,
       -- ... --
       u0_.gender AS gender19,
       -- ... --
       COUNT(DISTINCT u1_.id) AS sclr32,
       COUNT(DISTINCT u2_.id) AS sclr33
FROM users u0_
LEFT JOIN map_user_friend m4_ ON u0_.id = m4_.friend_id
LEFT JOIN users u3_ ON u3_.id = m4_.user_id
LEFT JOIN map_user_friend m5_ ON u0_.id = m5_.friend_id
LEFT JOIN users u1_ ON u1_.id = m5_.user_id
AND (u1_.gender = ?)
LEFT JOIN map_user_friend m6_ ON u0_.id = m6_.friend_id
LEFT JOIN users u2_ ON u2_.id = m6_.user_id
AND (u2_.gender = ?)
WHERE u3_.id = ?
GROUP BY u0_.id

参数是m代表男性,f代表女性,21代表当前用户。现在遵循奇怪的行为。 Doctrine\Common\Util\Debug::dump($qb-&gt;getQuery()-&gt;execute()); 回我

array (size=2)
  0 =>
    array (size=3)
      'user' => string 'Oneup\UserBundle\Entity\User' (length=28)
      'male_friends' => string '2' (length=1)
      'female_friends' => string '2' (length=1)
  1 =>
    array (size=3)
      'user' => string 'Oneup\UserBundle\Entity\User' (length=28)
      'male_friends' => string '0' (length=1)
      'female_friends' => string '0' (length=1)

如果我直接在 mysql 中执行查询,我会得到另一个计数:

+--------------+-----------------+-----------------+
| username0    | sclr32 (male)   | sclr33 (female) |
+--------------+-----------------+-----------------+
| foobar12     | 1               | 2               |
+--------------+-----------------+-----------------+
| foobar2      | 2               | 0               |
+--------------+-----------------+-----------------+

这是正确的。这是一个教义错误,还是我只是做错了?

【问题讨论】:

  • 也许是我,但我在比较原始 sql 查询的结果和 Doctrine 的结果时遇到了一些困难。也许是因为我不明白输入是什么,实体的 id 等等!请问,你能更好地解释输入/输出吗?

标签: sql symfony doctrine-orm


【解决方案1】:

回答我自己的问题,错误出在存储库中的参数上

   ->leftJoin('u.friendsOf', 'mf', 'with', 'mf.gender = :gender')->setParameter('gender', 'm')
   ->leftJoin('u.friendsOf', 'ff', 'with', 'ff.gender = :gender')->setParameter('gender', 'w')

错了。教义对两个条目都取第二个值。

   ->leftJoin('u.friendsOf', 'mf', 'with', 'mf.gender = :male')->setParameter('male', 'm')
   ->leftJoin('u.friendsOf', 'ff', 'with', 'ff.gender = :female')->setParameter('female', 'w')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    相关资源
    最近更新 更多