Если у меня есть связанный объект, который является коллекцией, какие параметры у вас есть при извлечении?
например, допустим, что у меня есть объект $view
с этим определением внутри него:
/** * @ORM\OneToMany(targetEntity="\Gutensite\CmsBundle\Entity\View\ViewVersion", mappedBy="entity") * @ORM\OrderBy({"timeMod" = "DESC"}) */ protected $versions; public function getVersions() { return $this->versions; }
И я хочу получить все версии, связанные с сущностью, как это:
$view->getVersions();
Это вернет коллекцию. Отлично. Но можно ли взять эту коллекцию и отфильтровать ее по критериям, например, более поздней, чем определенная дата? Или заказать его по некоторым (другим) критериям?
Или на данный момент вы просто ожидаете сделать запрос в репозитории:
$versions = $em->getRepository("GutensiteCmsBundle:View\ViewVersion")->findBy(array( array( 'viewId', $view->getId(), 'timeMod', time()-3600 ) // order by array('timeMod', 'DESC') ));
В последних версиях Doctrine есть удивительно неизвестная особенность, которая делает эти запросы намного проще.
Кажется, у него нет имени, но вы можете прочитать об этом в документах Doctrine в разделе 9.8 «Фильтрация коллекций» .
В коллекциях есть API фильтрации, который позволяет обрезать части данных из коллекции. Если коллекция еще не загружена из базы данных, API-интерфейс фильтрации может работать на уровне SQL, чтобы обеспечить оптимизированный доступ к большим коллекциям.
В вашем случае вы можете написать такой метод, как на объекте View
.
use Doctrine\Common\Collections\Criteria; class View { // ... public function getVersionsNewerThan(\DateTime $time) { $newerCriteria = Criteria::create() ->where(Criteria::expr()->gt("timeMod", $time)); return $this->getVersions()->matching($newerCriteria); } }
Это сделает одну из двух вещей:
Это действительно здорово, потому что подключение методов репозитория к вашим представлениям обычно беспорядочно и подвержено перерыву.
Мне также нравится ответ @ igor-pantovic, хотя я видел, как этот метод вызывает некоторые смешные ошибки.
Я бы лично избегал использования порядка по аннотации напрямую. Да, вы должны делать запрос так же, как если бы вы использовали необработанный SQL без Doctrine.
Тем не менее, я бы не сделал этого в тот момент, но даже раньше. В вашем конкретном случае я бы создал класс ViewRepository
:
class ViewRepository extends EntityRepository { public function findWithVersionsNewerThan($id, \DateTime $time) { return $this->createQueryBuilder('view') ->addSelect('version') ->join('view.versions', 'version') ->where('view.id = :id') ->andWhere('version.timeMod > :time') ->setParameter('time', $time) ->setParameter('id', $id) ->getQuery() ->getOneOrNullResult(); } }
Теперь вы можете сделать:
$yourDateTime = // Calculate it here ... ; $view = $em->getRepository("GutensiteCmsBundle:View\ViewVersion")->findWithVersionsNewerThan($yourDateTime); $versions = $view->getVersions(); // Will only contain versions newer than datetime provided
Я пишу код с верхней части моей головы здесь, поэтому очень жаль, если прошита синтаксис или ошибка имени метода.