Эффективный способ отображения подмножества коллекции Doctrine в ветке

У меня есть объект Symfony, у которого есть отображение OneToMany с предложением OrderBy, например:

/**
 * @ORM\OneToMany(targetEntity = "App\Entity\News", mappedBy = "category", orphanRemoval=true)
 * @ORM\OrderBy({"id" = "DESC"})
 */
private $news;

Предполагая, что я хотел бы отображать только записи n в Twig, у меня были бы варианты либо перебрать его и игнорировать все, что находится после loop.index n, либо, скорее, использовать кусочек. Однако у этих опций есть обратная сторона: если новостей много, все они будут загружены, что не очень эффективно.

Другой вариант - использовать критерии в контроллере или объекте для ограничения количества загружаемых объектов. Если я правильно понял здесь, он должен изменить запрос доктрины напрямую и, таким образом, не будет влиять на производительность. Это лучшая практика, или было бы лучше иметь собственный построитель запросов в контроллере или функцию в репозитории?

Если я правильно понял, что вы говорите о ленивой загрузке, есть несколько способов ее остановить: сначала в сопоставлении -> eager = FETCH; второй с индивидуальным запросом для присоединения только того, что вам нужно; третий способ - использовать $ qb-> getQuery () -> setHint (\ Doctrine \ ORM \ Query :: HINT_FORCE_PAR‌ TIAL_LOAD, true). Эти варианты сейчас приходят мне в голову, надеюсь помочь вам

l13 27.10.2018 08:59
За пределами сигналов Angular: Сигналы и пользовательские стратегии рендеринга
За пределами сигналов Angular: Сигналы и пользовательские стратегии рендеринга
TL;DR: Angular Signals может облегчить отслеживание всех выражений в представлении (Component или EmbeddedView) и планирование пользовательских...
Sniper-CSS, избегайте неиспользуемых стилей
Sniper-CSS, избегайте неиспользуемых стилей
Это краткое руководство, в котором я хочу поделиться тем, как я перешел от 212 кБ CSS к 32,1 кБ (сокращение кода на 84,91%), по-прежнему используя...
1
1
172
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Фактически вы можете установить связь $news как EXTRA_LAZY и использовать функцию $news->slice() без запуска полной нагрузки, как указано в официальная документация:

If you mark an association as extra lazy the following methods on collections can be called without triggering a full load of the collection:

Collection#contains($entity)
Collection#containsKey($key) (available with Doctrine 2.5)
Collection#count()
Collection#get($key) (available with Doctrine 2.4)
Collection#slice($offset, $length = null)

Поэтому ваше объявление должно выглядеть следующим образом:

/**
 * @ORM\OneToMany(targetEntity = "App\Entity\News", mappedBy = "category", orphanRemoval=true, fetch = "EXTRA_LAZY")
 * @ORM\OrderBy({"id" = "DESC"})
 */
private $news;

Очень красиво, именно то, что я искал!

wawa 28.10.2018 19:45

Другие вопросы по теме