【问题标题】:Check if an array contains any element of another array in doctrine query builder检查一个数组是否包含教义查询生成器中另一个数组的任何元素
【发布时间】:2017-05-31 19:37:43
【问题描述】:

我想知道是否可以在学说查询生成器中检查一个数组是否包含另一个数组的任何元素。

在我的情况下,我想获取在参数中传递的数组中至少具有一个类别的所有产品(项目)。

项目和类别之间的关系:

/**
 *  @ORM\ManyToMany(targetEntity="Category")
 *  @ORM\JoinTable(name="items_categories",
 *      joinColumns={@ORM\JoinColumn(name="item_id", referencedColumnName="id", nullable=false)},
 *      inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=false)}
 *      )
 */
private $categories;

我从项目存储库中的第一次尝试(如果我只有 一个要检查的值):

public function getListItemsFromCatList($listCat) {
    $qb = $this->createQueryBuilder('i');

    $qb->select('i')
            ->where($qb->expr()->like('i.categories', ':listCat'))
            ->setParameter('listCat', '%"' . $listCat . '"%');

    return $qb->getQuery()->getResult();
}

$listCat 是一个类别实体数组:

array (size=5)
  0 => 
    object(ItemBundle\Entity\Category)[518]
      private 'id' => int 22
      private 'children' => 
        object(Doctrine\ORM\PersistentCollection)[520]
          private 'snapshot' => 
            array (size=2)
              ...
          private 'owner' => 
            &object(ItemBundle\Entity\Category)[518]
          private 'association' => 
            array (size=15)
              ...
          private 'em' => 
            object(Doctrine\ORM\EntityManager)[796]
              ...
          private 'backRefFieldName' => string 'parent' (length=6)
          private 'typeClass' => 
            object(Doctrine\ORM\Mapping\ClassMetadata)[579]
              ...
          private 'isDirty' => boolean false
          protected 'collection' => 
            object(Doctrine\Common\Collections\ArrayCollection)[515]
              ...
          protected 'initialized' => boolean true
      private 'parent' => null
      private 'name' => string 'Luxe' (length=4)
  1 => 
    object(ItemBundle\Entity\Category)[504]
      private 'id' => int 25
      private 'children' => 
        object(Doctrine\ORM\PersistentCollection)[505]
          private 'snapshot' => 
            array (size=0)
              ...
          private 'owner' => 
            &object(ItemBundle\Entity\Category)[504]
          private 'association' => 
            array (size=15)
              ...
          private 'em' => 
            object(Doctrine\ORM\EntityManager)[796]
              ...
          private 'backRefFieldName' => string 'parent' (length=6)
          private 'typeClass' => 
            object(Doctrine\ORM\Mapping\ClassMetadata)[579]
              ...
          private 'isDirty' => boolean false
          protected 'collection' => 
            object(Doctrine\Common\Collections\ArrayCollection)[500]
              ...
          protected 'initialized' => boolean false
      private 'parent' => 
        object(ItemBundle\Entity\Category)[512]
          private 'id' => int 23
          private 'children' => 
            object(Doctrine\ORM\PersistentCollection)[513]
              ...
          private 'parent' => 
            object(ItemBundle\Entity\Category)[518]
              ...
          private 'name' => string 'Bijoux' (length=6)
      private 'name' => string 'Bagues' (length=6)

【问题讨论】:

  • 查看我认为可能有效的编辑#2。

标签: php arrays doctrine-orm doctrine symfony-3.1


【解决方案1】:

我会添加一个连接来解决它。

public function getListItemsFromCatList($listCat) {

    $em = $this->getDoctrine()->getManager();

    $qb = $em->createQueryBuilder();
    $qb->select('i')           
        ->from('AppBundle:Item', 'i')
        ->innerJoin('i.categories','cat')
        ->where('cat IN (:listCat)')
       ->setParameter('listCat', $listCat);

    return  = $qb->getQuery()->getResult();
}

请注意,此方法将过滤项目内的类别。这意味着当您尝试从给定项目i$i->getCategories() 中获取类别时,它将仅返回与$listCat 匹配的i 中的类别。

如果您需要使用每个项目的所有类别,即使这些类别与$listCat 不匹配。我会建议您使用子查询进行过滤,并使用主查询返回完整的项目。如果您需要任何进一步的帮助,请发表评论。

【讨论】:

  • 在我的情况下,只要有与$listCat匹配的类别就可以了。所以谢谢你的回答
【解决方案2】:

试试这样的查询生成器:

$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$qb->select('i')
    ->from('AppBundle:Item', 'i')
    ->where('i.categories LIKE :listCat')
    ->setParameter('listCat', '%"' . $listCat . '"%');

return  = $qb->getQuery()->getResult();

我认为这应该可行。我假设您使用的 Doctrine 中的实体称为 Item

编辑 #2 - 基于 cmets

您需要遍历数组并获取名称(我认为),我认为这是您正在寻找的类别。在这段代码中,我展示了循环创建一个$cats 变量,然后在IN 查询中使用它。

foreach ($listCat as $item){
    $cats = $cats . "'" . $item.getName() . "'".',';
}
$cats = substr($cats, -1);


$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$qb->select('i')
    ->from('AppBundle:Item', 'i')
    ->where("i.categories IN (:listCat)")
    ->setParameter('listCat', $cats);

return  = $qb->getQuery()->getResult();

你可以试试吗?我认为你需要这样的东西。

【讨论】:

  • 这个和我的测试一样。有关信息,$listcat 是类别实体的数组。所以这行不通(我刚试过,我得到以下错误:注意:数组到字符串的转换)
  • $listCat 是一个数组吗?
  • 请举例说明$listCat 包含的内容。也许您可以改用IN
  • 完成,但我认为这不会起作用,因为i.categories 也是一个集合。什么会很棒,会有这个post的行为
  • 我收到此错误:[Semantical Error] line 0, col 47 near 'categories IN': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected. 我认为这很正常,因为 IN 子句仅在左侧(i.categories)等待一个值
猜你喜欢
  • 2023-03-08
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2017-03-03
  • 2022-08-04
  • 2021-01-30
相关资源
最近更新 更多