如何使用Doctrine Criteria过滤掉数组属性?

时间:2017-01-13 16:25:46

标签: php symfony doctrine-orm doctrine

我在Symfony实体类中添加虚拟属性。此属性应基于另一个表数据计算 - 特别是在 Doctrine数组类型的列上。

class RelatedEntity
{

    /* ... */

    /**
     * @ORM\Column(type="array")
     */
    protected $type;

关键是我想使用Doctrine Criteria ,因为它应该在SQL级别进行优化。所以我这样做了:

public function getCreated()
{
    $criteria = Criteria::create()->where(Criteria::expr()->contains('type', 'create'));
    $relatedEntity = $this->getRelatedEntities()->matching($criteria);

    if (!$relatedEntity) {
        return null;
    }

    return $relatedEntity->getTimestamp();
}

但我得到一个空的结果集。即使Doctrine正在构建一个正确的SQL语句,当我手动将其键入PostgreSQL数据库时,它也能正常工作。

...WHERE type LIKE '%create%'

这种方法有什么问题以及如何解决?现在我使用ArrayCollection过滤器方法完成了这个技巧,但它加载了我不需要的所有相关实体。 / p>

感谢您的任何想法。

编辑:这不是上述问题的重复,因为我无法在实体中使用 EntityManager EntityRepository 。我需要使用Criteria,因此问题中提出的解决方案并不适用于我。

1 个答案:

答案 0 :(得分:0)

检查getRelatedEntities()

的结果

根据此集合的创建方式,可能会发生以下任何一种情况。特别是,它可能正在使用实体别名,或者可能不会返回任何与您Criteria匹配的实体别名。

  1. 从别名实体填充的集合(即:通过QueryBuilder加入/选择)。
    • 如果通过QueryBuilder由Doctrine填充getRelatedEntities,您可能会对实体设置别名。
    • EX。:$queryBuilder->addSelect('thing')->leftJoin('root_alias.entity', 'thing')
    • 在这种情况下,Criteria必须使用别名:
      • Criteria::expr()->contains('thing.type', 'create')
  2. 不符合条件。
    • 在过滤之前转储您的收藏集,这可能是您的查询已经过滤掉任何可能的匹配项的简单情况。
  3. 测试您的标准

    考虑到所有事情,没有任何关于您尝试过滤的集合结构的线索,我们只能评估您的标准。因此,请测试您的标准,并检查您尝试过滤的集合的内容。

    $criteria = Criteria::create()->where(Criteria::expr()->contains('type', 'create'));
    
    $collection = new ArrayCollection([
        [
            'key' => 1,
            'type' => 'somethingcreatesomething',
        ],
        [
            'key' => 2,
            'type' => 'abra',
        ],
        [
            'key' => 3,
            'type' => 'cadabra',
        ],
        [
            'key' => 4,
            'type' => 'alacreate',
        ],
    ]);
    
    dump($collection->matching($criteria));
    

    结果

    Doctrine\Common\Collections\ArrayCollection {#2536
      -elements: array:2 [
        0 => array:2 [
          "key" => 1
          "type" => "somethingcreatesomething"
        ]
        3 => array:2 [
          "key" => 4
          "type" => "alacreate"
        ]
      ]
    }