DQL 的 Doctrine 2 反向成员

Doctrine 2 reverse MEMBER OF DQL

我有 Profile class 与 ManyToMany 关系 "links" 和 Link class。 我需要构建 DQL 查询以获取某些配置文件 的所有 link,而没有 反向关系(link->配置文件)。

第一个想法是简单使用 "MEMBER OF" 但看起来没有直接关系是不可能的。

MEMEBER OF 正在构建子查询 sql。也许有办法做类似的事情?

我不能只使用

SELECT l FROM Profile p LEFT JOIN p.links l WHERE p.user = :user

但我能做到:

SELECT e FROM Link WHERE e.id IN (SELECT l FROM Profile p LEFT JOIN p.links l WHERE p.user = :user)

所以我生成了这个 SQL:

SELECT ... FROM Link t0_ 
   WHERE t0_.id IN (
      SELECT t1_.id FROM Profile a2_ 
      LEFT JOIN profile_link p3_ ON a2_.user_id = p3_.profile_user_id 
      LEFT JOIN Link t1_ ON t1_.id = p3_.link_id 
      WHERE a2_.user_id = ?
   )

有什么方法可以在不加入配置文件的情况下直接为 table profile_link 构建子查询?

类似于:

SELECT ... FROM Link t0_ 
   WHERE t0_.id IN (
      SELECT l.link_id FROM profile_link l 
      WHERE l.profile_id = :user
   )

P.S。无需使用配置文件 table.

profile_link.profile_id = profile.user_id = user.id = :user

我需要一个 DQL 查询构建器来构建具有 filter/sorter/grouper 支持的更复杂的查询。我不能在这里使用本机查询或修改实体 class。也许某种自定义 DQL 函数可以解决它。

我相信你想多了。

您可以通过定义的链接关系获取个人资料实体的链接。

我假设您的个人资料 class 看起来像:

use Doctrine\ORM\Mapping as ORM;

class Profile
{
    /**
     * @var integer
     *
     * @ORM\Column(name="user_id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
     private $id;

     /**
      * @ORM\ManyToMany(targetEntity="Link")
      * @ORM\JoinTable(name="profile_link",
      *      joinColumns={@ORM\JoinColumn(name="profile_user_id", referencedColumnName="user_id")},
      *      inverseJoinColumns={@ORM\JoinColumn(name="link_id", referencedColumnName="id")}
      *      )
      **/
     protected $links;

     public function getLinks()
     {
         return $this->links;
     }

您可以通过以下方式实现您想要的:

  • 正在加载配置文件实体
  • 获得链接关系
  • 遍历返回的集合,这取决于 relation fetch mode(急切的、懒惰的或极度懒惰的),如果尚未从上述步骤中获取实体,则将导致获取实体。

在您的控制器中,只需执行以下操作:

$profile = $em->getRepository('AppBundle\Entity\Profile')->find(1);
$links = $profile->getLinks();
foreach($links as $link) {
    echo $link->getId();
}

这样将执行 2 个查询:

1) 获取配置文件行,例如:

SELECT t0.user_id AS user_id_1 FROM profile t0 WHERE t0.user_id = ?

2) 获取相关链接,例如:

SELECT t0.id AS id_1 FROM link t0 INNER JOIN profile_link ON t0.id = profile_link.link_id WHERE profile_link.profile_user_id = ?

在最后一个查询中,只加入了映射 table,没有加入配置文件 table。返回的行不包含配置文件数据。

我放弃了。

ManyToMany realtion 是一对简单的 OneToMany realtions,所以我创建了 class 来表示它。

class ProfileLink{

    /** 
     * @ORM\Id
     * @ORM\OneToMany(targetEntity="Profile")
     */
    protected $profile;


    /** 
     * @ORM\Id
     * @ORM\OneToMany(targetEntity="Link")
     */
    protected $link;
}

现在我可以在 Link class

上使用没有反向部分的 DQL
SELECT p FROM ProfileLink LEFT JOIN p.link WHERE p.profile = :user_id;