Я использую Doctrine\Common\Collections\Criteria::expr()
( НЕ выражение построителя запроса).
Похоже, что операторы isNotNull()
и notLike()
не реализованы в этом классе.
Каков наилучший способ сделать isNotNull()
и notLike()
в этом случае?
Я использую Doctrine\Common\Collections\Criteria::expr()
( НЕ выражение построителя запроса).
Похоже, что операторы isNotNull()
и notLike()
не реализованы в этом классе.
Каков наилучший способ сделать isNotNull()
и notLike()
в этом случае?
Чтобы иметь значение 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')
является эквивалентом property LIKE %value%
SQL property LIKE %value%
. Однако он не допускает изменения в value%
или %value
но запрашивает извлечение (по состоянию на 2.5.4) с предлагаемыми startsWith
и endsWith
использования, которые были объединены с главным, - поэтому может быть выпущено с 2.5.5.
К сожалению, для Criteria::expr()->notLike()
и других вариантов LIKE
, \Doctrine\Common\Collections\ExpressionBuilder
используемый Criteria, не поддерживает их.
Кроме того, если оператор сравнения не определен (например, 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));
});
}
}
$repo->getCollectionFieldNotLike('value');
$repo->getCollectionFieldLike('value');
Для процедурного синтаксиса комбинация обоих на репозитории.
$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'));
});
Имейте в виду, что, как указано выше, это приведет к полному чтению таблицы из коллекции, поскольку для фильтрации результатов потребуется извлечь записи.