【问题标题】:(Doctrine) Select where array collection is not empty?(教义)选择数组集合不为空的地方?
【发布时间】:2019-01-18 20:37:21
【问题描述】:

我有一个班级帖子:

/**
 * @ORM\Entity(repositoryClass="App\Repository\PostRepository")
 */
class Post
{
    const TYPE_TEXT   = 1;
    const TYPE_PHOTOS = 2;
    const TYPE_VIDEO  = 3;

    /**
     * @ORM\OneToMany(targetEntity="Photo", mappedBy="post")
     */
    private $photos;

    and other properties, methods, etc... 

我只想带回有照片的帖子。

我有一个 DQL 查询,例如:

    $qb = $this->createQueryBuilder('p');
    $qb->select('p, postPhotos, etc...')
        ->leftJoin('p.photos', 'postPhotos')
        ->leftJoin('p.videos', 'postVideos')
        etc...

    if ($mediaType != null)
    {
        switch ($mediaType) {
            case Post::TYPE_PHOTOS:
                $qb->andWhere('postPhotos != :null')
                    ->setParameter('null', null);

"!= :null" 不起作用,COUNT(postPhotos) 也不起作用(显然是出于聚合原因)。

有没有一种方法可以让我只指定包含 1 张或更多照片的帖子?

【问题讨论】:

    标签: doctrine arraycollection


    【解决方案1】:

    快速回答:如果您将 leftJoin 的用法替换为 just join(或 innerJoin),那么您将得到您想要的:仅包含至少 1 张照片的帖子。

    详情

    如果您查看此有用的 SO Q&A:

    Different MySQL Join Methods

    ...您会发现一些出色的维恩图显示了左连接和内连接之间的区别。然后,如果您查看 Doctrine 的 Doctrine\ORM\QueryBuilder 类,您会发现它们具有三个连接方法:

    • join(只调用innerJoin)
    • innerJoin
    • leftJoin
        /**
         * Creates and adds a join over an entity association to the query.
         *
         * The entities in the joined association will be fetched as part of the query
         * result if the alias used for the joined association is placed in the select
         * expressions.
         *
         * <code>
         *     $qb = $em->createQueryBuilder()
         *         ->select('u')
         *         ->from('User', 'u')
         *         ->join('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
         * </code>
         *
         * @param string      $join          The relationship to join.
         * @param string      $alias         The alias of the join.
         * @param string|null $conditionType The condition type constant. Either ON or WITH.
         * @param string|null $condition     The condition for the join.
         * @param string|null $indexBy       The index for the join.
         *
         * @return self
         */
        public function join($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
        {
            return $this->innerJoin($join, $alias, $conditionType, $condition, $indexBy);
        }
    
        /**
         * Creates and adds a join over an entity association to the query.
         *
         * The entities in the joined association will be fetched as part of the query
         * result if the alias used for the joined association is placed in the select
         * expressions.
         *
         *     [php]
         *     $qb = $em->createQueryBuilder()
         *         ->select('u')
         *         ->from('User', 'u')
         *         ->innerJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
         *
         * @param string      $join          The relationship to join.
         * @param string      $alias         The alias of the join.
         * @param string|null $conditionType The condition type constant. Either ON or WITH.
         * @param string|null $condition     The condition for the join.
         * @param string|null $indexBy       The index for the join.
         *
         * @return self
         */
        public function innerJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
        {
            $parentAlias = substr($join, 0, strpos($join, '.'));
    
            $rootAlias = $this->findRootAlias($alias, $parentAlias);
    
            $join = new Expr\Join(
                Expr\Join::INNER_JOIN, $join, $alias, $conditionType, $condition, $indexBy
            );
    
            return $this->add('join', [$rootAlias => $join], true);
        }
    
        /**
         * Creates and adds a left join over an entity association to the query.
         *
         * The entities in the joined association will be fetched as part of the query
         * result if the alias used for the joined association is placed in the select
         * expressions.
         *
         * <code>
         *     $qb = $em->createQueryBuilder()
         *         ->select('u')
         *         ->from('User', 'u')
         *         ->leftJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
         * </code>
         *
         * @param string      $join          The relationship to join.
         * @param string      $alias         The alias of the join.
         * @param string|null $conditionType The condition type constant. Either ON or WITH.
         * @param string|null $condition     The condition for the join.
         * @param string|null $indexBy       The index for the join.
         *
         * @return self
         */
        public function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
        {
            $parentAlias = substr($join, 0, strpos($join, '.'));
    
            $rootAlias = $this->findRootAlias($alias, $parentAlias);
    
            $join = new Expr\Join(
                Expr\Join::LEFT_JOIN, $join, $alias, $conditionType, $condition, $indexBy
            );
    
            return $this->add('join', [$rootAlias => $join], true);
        }
    
    
    

    将代码更改为使用 innerJoin(或仅加入)将导致 Doctrine 在生成的 SQL 中发出 INNER JOIN,这将仅返回联接两侧都存在“某物”的记录,因此,任何没有照片不会包含在结果中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多