我正在使用Doctrine\Common\Collections\Criteria::expr()(不是查询构建器表达式).
似乎isNotNull()并notLike()没有在这个类中实现运算符.
什么是做的最好的方式isNotNull(),并notLike()在这种情况下?
fyr*_*rye 17
有一个is not null像Criteria::expr()->isNotNull('field')你可以使用的行为
$criteria = Criteria::create();
$expr = $criteria::expr();
$collection->matching($criteria->where($expr->neq('field', null)));
Run Code Online (Sandbox Code Playgroud)
这与表达式构建器创建的方式匹配,isNull但将比较运算符更改为NEQvia.
return new Comparison($field, Comparison::EQ, new Value(null));
Run Code Online (Sandbox Code Playgroud)
然后由QueryExpressionVisitorand 检查BasicEntityPersister,用于构建查询.
对于Criteria::expr()->like()功能,Criteria::expr()->contains('property', 'value')相当于SQL property LIKE %value%.但是,它不允许更改为value%或者%value是一个拉取请求 (从2.5.4开始)与建议startsWith和endsWith已与主程序合并的方法 - 因此可能会以2.5.5发布.
遗憾的是Criteria::expr()->notLike(),对于其他LIKE变体,\Doctrine\Common\Collections\ExpressionBuilderCriteria使用的不支持它们.
此外,如果比较操作符没有定义(如CONTAINS),错误被抛出QueryExpressionVisitor并且BasicEntityPersister,这防止手动定义自己的Comparison功能.
最好的替代方法是使用自定义存储库和DBAL查询构建器表达式来替换所需的功能.
使用自定义实体存储库过滤结果集将阻止对表的集合进行全表读取,并在使用缓存时提高速度.
另一种方法是使用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));
});
}
}
Run Code Online (Sandbox Code Playgroud)
$repo->getCollectionFieldNotLike('value');
$repo->getCollectionFieldLike('value');
Run Code Online (Sandbox Code Playgroud)
对于存储库上的两者的过程语法组合.
$criteria = Criteria::create();
$expr = $criteria::expr();
$criteria->where($expr->neq('field', null));
$collection = $entityManager->getRepository('app:MyEntity')->matching($criteria);
$collectionNotLike = $collection->filter(function($a) {
return (false === strpos($a->getField(), 'value'));
});
Run Code Online (Sandbox Code Playgroud)
请记住,如上所述,这将强制对集合进行全表读取,因为它需要检索记录才能过滤结果.