【问题标题】:Many to many relation and query builder多对多关系和查询构建器
【发布时间】:2014-12-03 11:14:33
【问题描述】:

我想扩展我的用户存储库。我将找到具有指定角色的所有用户或 满足附加条件。

我尝试使用查询生成器进行一些查询,但没有成功。

这是我的数据库结构的示例。

表名:用户

+----+----------+-----------+
| id | isActive | isDeleted |
+----+----------+-----------+
|  1 |        1 |         0 |
+----+----------+-----------+

表名:角色

+----+-------+
| id | name  |
+----+-------+
|  1 | Admin |
+----+-------+

表名:user_role

用户和角色之间的多对多关系

+---------+---------+
| user_id | role_id |
+---------+---------+
|       1 |       1 |
+---------+---------+

表名:距离

用户和桌子距离之间的OneToMany关系

+----+---------+-----+------+
| id | user_id | lat | long |
+----+---------+-----+------+
|  1 |       1 |     |      |
+----+---------+-----+------+

我写了一个普通的sql查询,这对我来说是正确的,但我不知道我该如何实现 与查询生成器的多对多关系。

SELECT u.id 
FROM user as u,  user_role  as ur 
WHERE u.id=ur.user_id and ur.role_id=1 OR 
(u.id not in (select user_id from distance) and ur.role_id=1 and u.id=ur.user_id);

谁能告诉我如何解决这个问题?

更新

出于可读性和清晰的考虑,我将只显示实体的某些部分。

class User implements AdvancedUserInterface, \Serializable
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Exclude
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="App\UserBundle\Entity\Role", inversedBy="users")
     *
     */
    protected $roles;

    /**
     * @ORM\OneToMany(targetEntity="App\UserBundle\Entity\Distance", mappedBy="user", cascade={"persist", "remove"})
     * @Exclude
     */
    protected $distance;

}


class Role implements RoleInterface
{

    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="name", type="string", length=255)
     * @Exclude
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity="App\UserBundle\Entity\User", mappedBy="roles")
     */
    private $users;
}


class Distance
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="distance", cascade={"persist", "remove"})
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

}

【问题讨论】:

  • 你能发布你的实体吗?
  • 我添加了我的实体的一些重要部分,可以吗?
  • Mab82x,您可以在 cmets 中通过在用户名前添加“@”符号来“ping”用户。例如,您可以说 - @LordZed,我添加了我的实体的一些重要部分。这足够了吗? - 并且会通知发布者。
  • @AHiggins 非常感谢这个提示,我以前不知道这个:)

标签: symfony doctrine


【解决方案1】:

你可以试试这样的 DQL(或类似的)。请查看Doctrine DQL documenation

SELECT u FROM App\UserBundle\Entity\User u
INNER JOIN u.role r
LEFT JOIN u.distance d
WHERE r.id = 1 OR (r.id = 1 AND d IS NULL)

顺便说一句,你确定你的 SQL 没问题吗?我不确定这是否与

给出相同的结果
SELECT u.id 
FROM user as u,  user_role  as ur 
WHERE u.id=ur.user_id and ur.role_id=1

那么 DQL 将是微不足道的

SELECT u FROM App\UserBundle\Entity\User u
INNER JOIN u.role r
WHERE r.id = 1

【讨论】:

    【解决方案2】:

    @l3l0 非常感谢,这解决了我的问题:)

    我现在在我的用户存储库中添加了以下功能,一切正常:)

    public function getUsers2Crawl($role)
    {
        $query = $this->getEntityManager()->createQuery('SELECT u FROM App\UserBundle\Entity\User u INNER JOIN u.roles r LEFT JOIN u.distance d WHERE r.id = $role->getId() OR (r.id = $role->getId() AND d IS NULL)');
        return $query->getResult();
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-19
      • 2019-04-24
      • 1970-01-01
      • 1970-01-01
      • 2013-05-02
      • 2015-07-13
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      相关资源
      最近更新 更多