我正在使用Doctrine\Common\Collections\Criteria::expr()
( 不查询构建器表达式)。
似乎isNotNull()
和notLike()
运算符未在此类中实现。
在这种情况下,isNotNull()
和notLike()
的最佳方式是什么?
答案 0 :(得分:16)
要让is not null
像Criteria::expr()->isNotNull('field')
一样使用
$criteria = Criteria::create();
$expr = $criteria::expr();
$collection->matching($criteria->where($expr->neq('field', null)));
这与表达式构建器创建isNull
的方式相同,但是将比较运算符更改为NEQ
。
return new Comparison($field, Comparison::EQ, new Value(null));
然后由QueryExpressionVisitor
和BasicEntityPersister
检查,用于构建查询。
对于Criteria::expr()->like()
功能,Criteria::expr()->contains('property', 'value')
等同于SQL property LIKE %value%
。但是,它不允许更改为value%
或%value
,而是pull request (从2.5.4开始)与建议的startsWith
和{ {1}}已与master合并的方法 - 因此可能会以2.5.5发布。
不幸的是,对于endsWith
和其他Criteria::expr()->notLike()
变体,Criteria使用的LIKE
不支持它们。
此外,如果未定义比较运算符(例如\Doctrine\Common\Collections\ExpressionBuilder
),则CONTAINS
和QueryExpressionVisitor
会引发错误,从而阻止手动定义您自己的BasicEntityPersister
功能。
最好的替代方法是使用自定义存储库和DBAL查询构建器表达式来代替所需的功能。
使用自定义实体存储库过滤结果集将阻止对集合进行全表读取,并在使用缓存时提高速度。
另一种方法是使用Comparison
检索集合中特定的对象子集。
filter
class MyEntity
{
public function getCollectionFieldNotLike($value)
{
return $this->getCollection()->filter(function($a) use ($value) {
return (false === stripos($a->getField(), $value));
});
}
public function getCollectionFieldLike($value)
{
return $this->getCollection()->filter(function($a) use ($value) {
return (false !== stripos($a->getField(), $value));
});
}
}
对于存储库的两者的程序语法组合。
$repo->getCollectionFieldNotLike('value');
$repo->getCollectionFieldLike('value');
请记住,如上所述,这将强制对集合进行全表读取,因为它需要检索记录才能过滤结果。