Symfony错误:无效的PathExpression。必须是CollectionValuedAssociationField

时间:2017-11-09 13:02:42

标签: list symfony filter doctrine query-builder

我使用查询构建器来设置与其他实体具有不同关系的文档列表。该列表还包括该查询构建器中所有实体的过滤器表单。 到目前为止,它对所有这些都很好,但是一旦我添加了$ products实体,它就不再起作用了。 我的代码:

 $qb = $em->createQueryBuilder();
          $query = $qb->select('d', 'p')
          ->from('DocumentBundle:Document', 'd')
          ->innerJoin('d.products', 'p')
          ->orderBy('d.id', 'DESC')
          ->join('d.type', 'dt')
          ->join('d.status', 's');


        if(count($type) > 0){
          $query->andwhere($query->expr()->in('d.type', ':type'))
            ->setParameter('type',$type);
          }
          if(count($status) > 0) {
              $query->andWhere($query->expr()->in('d.status', ':status'))
              ->setParameter('status', $status);
          }

          if(count($markets) > 0){
            $query->andWhere(':marketIds MEMBER OF d.markets')
              ->setParameter('marketIds',$markets);
            }
            else{
            $query->andWhere(':marketIds MEMBER OF d.markets')
              ->setParameter('marketIds',$userMarkets);
            }

          if(count($airlines) > 0){
            $query->andWhere(':airlineIds MEMBER OF d.airlines')
              ->setParameter('airlineIds',$airlines);
            }else{
            $query->andWhere(':airlineIds MEMBER OF d.airlines')
              ->setParameter('airlineIds',$userAirlines);
            }

          if(count($products) > 0){
            $query->andWhere(':productIds MEMBER OF p.id')
              ->setParameter('productIds',$products);
            }
          //   else{
          //   $query->andWhere(':productIds MEMBER OF p.id')
          //     ->setParameter('productIds',$currentuser->getProducts());
          //   }

          $query->andWhere('d.active = ?1')
                ->setParameter(1, $archive ? 0 : 1);
          return $query
            ->setFirstResult($page * $maxRows - $maxRows)
            ->setMaxResults($maxRows)
            ;

因此,对于类型和状态,我有一个ManyToOne关系,对于市场,航空公司和(麻烦制造者)产品,它是一个ManyToMany关系。

当前代码抛出异常:

  

[语义错误]第0行,第237行附近' id AND d.active':错误:   无效的PathExpression。必须是CollectionValuedAssociationField。

这个奇怪的是,我有另一个实体的另一个列表,它也与产品有一个ManyToMany关系,对于那个列表它正在工作..同样奇怪的是:对于那个其他列表我的查询看起来像那样:

 $qb = $em->createQueryBuilder();
    $query = $qb->select('a', 'p')
    ->from('AppBundle:Agency', 'a')
    ->innerJoin('a.products', 'p')
    ->orderBy('a.id', 'ASC');

    if(count($markets) > 0){
      $query->andWhere('a.market IN (:marketIds)')
        ->setParameter('marketIds',$markets);
      }
      else{
      $query->andWhere('a.market IN (:marketIds)')
        ->setParameter('marketIds',$currentUser->getMarkets());
      }

      if(count($products) > 0){
        $query->andWhere('p.id IN (:productIds)')
          ->setParameter('productIds',$products);
        }
        else{
        $query->andWhere('p.id IN (:productIds)')
          ->setParameter('productIds',$currentUser->getProducts());
        }

这是市场的ManyToOne和产品的ManyToMany ..

我尝试为我的文档使用相同的代码(p.id in(:productIds)...),这是有用的,所以我至少不会再出错了。但是,当我然后过滤某些东西(如市场,航空公司,产品等)时,它不再起作用,所以列表只是空的。过滤第二个列表是有效的。所以我真的不知道这是从哪里来的。 感谢您提前提供任何帮助!

代码更新

    $qb = $em->createQueryBuilder();
          $query = $qb->select('d', 'p', 'm', 'a')
          ->from('DocumentBundle:Document', 'd')
          ->innerJoin('d.products', 'p')
          ->innerJoin('d.markets', 'm')
          ->innerJoin('d.airlines', 'a')
          ->orderBy('d.id', 'DESC')
          ->join('d.type', 'dt')
          ->join('d.status', 's');
  if(count($type) > 0){
          $query->andwhere($query->expr()->in('d.type', ':type'))
            ->setParameter('type',$type);
          }
          if(count($status) > 0) {
              $query->andWhere($query->expr()->in('d.status', ':status'))
              ->setParameter('status', $status);
          }
if(count($markets) > 0){
            $query->andWhere('m.id IN (:marketIds)')
              ->setParameter('marketIds',$markets);
            }
          if(count($airlines) > 0){
            $query->andWhere('a.id IN (:airlineIds)')
              ->setParameter('airlineIds',$airlines);
            }
            if(count($products) > 0){
              $query->andWhere('p.id IN (:productIds)')
                ->setParameter('productIds',$products);
              }
$query->andWhere('d.active = :archiveParam')
                ->setParameter("archiveParam", $archive ? 0 : 1);
                dump($query->getQuery());

过滤适用于状态,类型和市场,但不适用于航空公司和产品。 任何想法?

重现问题

Filter Form

所以这是我的滤镜形式(不需要的滤镜是黑色的)。它们都是多选下拉列表。在筛选市场和状态时,列表仅减少到具有该特定状态或分配到所选市场的文档。 对于所有ManyToMany关系(市场,航空公司和产品),我有自己的数据库表,它们都包含数据。 嗯,我不知道还有什么可以帮助解决这个问题。让我知道!!

示例数据将是: 文件编号42被分配给航空公司LH和LX,分配给市场CA,MX和US以及产品Nr。因此,当过滤其中一个市场时,文档总是出现在列表中。但是当过滤其中一家航空公司或产品时,该列表仍然是空的..

还有一个编辑:我刚刚添加了产品过滤器,在我拥有产品过滤器之前,对航空公司的过滤实际上工作正常。即使我使用了“错误”#39;查询会员d.airlines ..

1 个答案:

答案 0 :(得分:0)

这部分

if(count($products) > 0){
    $query->andWhere(':productIds MEMBER OF p.id')
        ->setParameter('productIds',$products);
}

应该是这样的

if(count($products) > 0){
    $query->andWhere('p.id IN (:productIds) ')
        ->setParameter('productIds',$products);
}

您也在混合位置和命名参数。

$query->andWhere('d.active = :archiveParam')
    ->setParameter("archiveParam", $archive ? 0 : 1);