【问题标题】:Doctrine : SELECT a relationned entity教义:选择一个关联实体
【发布时间】:2018-01-10 16:05:43
【问题描述】:

我有 2 个实体:

  • LinkServInfra
  • 服务

LinkServInfra 实体:

  • 身份证
  • serv(关系 OneToOne 到 Serv)
  • infra(ManyToOne 到另一个实体)

现在,我想获取一个基于 infra 的 Serv 列表。

所以我在 LinkServInfraRepository 中尝试了:

    $qb = $this->createQueryBuilder('s')
            ->select('DISTINCT s.serv')
            ->where('s.infra = :infra')
            ->setParameter('infra', $infra);
    return $qb->getQuery()->getResult();

我得到一个错误:

    [Semantical Error] near 'serv FROM': Error: InvalidPathExpression. 
     Must be a StateFieldPathExpression.

(我首先尝试不使用 DISTINCT,然后根据此处找到的答案尝试使用它)。

查询似乎很好,因为它是:

    SELECT DISTINCT s.serv 
    FROM MyBundle\Entity\LinkServInfra s 
    WHERE s.infra = :infra

你会怎么做? 谢谢!

【问题讨论】:

    标签: symfony doctrine-orm symfony-2.7


    【解决方案1】:

    由于关系仅在 LinkServInfra 中而不在 Serv 中:

    我使用 LinkServInfra 中的关系来做到这一点...

        public function filter($type, $etat, $infra){
    
        $qb = $this->createQueryBuilder('l');
        $qb->where(' l.infra = :infra ')
           ->setParameter('infra', $infra);
    
        if( $type || $etat ){
           $qb->join('l.serv', 's')
           //where & setParameter for type
           //where & setParameter for detail
        }
    

    然后我调用函数filter

        $entities = $em->getRepository('linkServInfra')->filter(//...
        $servs = array();
        foreach($entities as $entity){
            $servs[] = $entity->getServ();
    
        }
    

    我想这不是最干净的解决方案,但它正在工作......

    【讨论】:

      【解决方案2】:

      我认为你不能在关系上使用DISTINCT,只能用于根实体别名

      您应该使用 Serv 实体作为根,并通过第二个实体加入 LinkServInfrainfra 实体。比如:

      $qb = $this->getDoctrine()
              ->getRepository(Serv::class)->createQueryBuilder('s')
              ->select('DISTINCT s')
              ->leftJoin("s.linkServInfra", "lsi")
              ->leftJoin("lsi.infra", "infra")
              ->where('infra.id = :infra')
              ->setParameter('infra', 1);
      

      或者,如果关系是单向并且您不想使其成为双向,则可以使用自定义连接:

      use Doctrine\ORM\Query\Expr\Join;
      
      $qb = $this->getDoctrine()
              ->getRepository(Serv::class)->createQueryBuilder('s')
              ->select('DISTINCT s')
              ->leftJoin(LinkServInfra::class, "lsi", Join::WITH, 'lsi.serv = s')
              ->leftJoin("lsi.infra", "infra")
              ->where('infra.id = :infra')
              ->setParameter('infra', 1);
      

      参考文献

      【讨论】:

      • Serv 不知道这种关系(由于某些原因我需要这样做......)所以s.linkServInfra 不存在,对吧?
      • 是的,你有一个单向关系。您可以将其设为双向。 docs.doctrine-project.org/projects/doctrine-orm/en/latest/…
      • 是的,但我不希望它是双向的(就像我说的那样,但这是另一个讨论)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      • 1970-01-01
      相关资源
      最近更新 更多