Dctrine 2反向成员

时间:2019-02-15 13:44:17

标签: doctrine-orm dql

我有 Profile 类,其中包含ManyToMany关系“链接”和 Link 类。 我需要构建DQL查询来获取某个配置文件的所有链接,这些链接没有没有反向关系(链接->配置文件)。

第一个想法是简单地使用“ 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 = ?
   )

有什么方法可以不通过概要文件联接而直接将子查询直接构建到表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。无需使用配置文件表。

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

我需要DQL查询构建器来构建具有过滤器/分类器/石斑鱼支持的更复杂的查询。我无法在此处使用本机查询或修改Entity类。也许某种自定义DQL函数可以解决它。

2 个答案:

答案 0 :(得分:1)

我相信您想得太多。

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

我认为您的个人资料类如下:

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 = ?

在上一个查询中,仅联接映射表,而不联接“个人档案”表。返回的行不包含配置文件数据。

答案 1 :(得分:0)

我放弃。

ManyToMany现实是一对简单的OneToMany现实,因此我创建了表示它的类。

class ProfileLink{

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


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

现在,我可以在 Link

上使用DQL,而无需使用反向部分
SELECT p FROM ProfileLink LEFT JOIN p.link WHERE p.profile = :user_id;