Я строй инструмента управления продуктом, где product
может иметь произвольное число attributes
, documents
, features
, images
, videos
, а также один type
, brand
и category
. Существует несколько других связанных таблиц, но этого достаточно, чтобы продемонстрировать проблему.Как уменьшить количество запросов, которые выполняет Doctrine?
Там в класс Модель называется ProductModel
, который содержит метод, как это (уменьшена для ясности):
public function loadValues() {
//Product entity data
$this->id = $this->entity->getId();
$this->slug = $this->entity->getSlug();
// One of each of these
$this->loadType();
$this->loadBrand();
$this->loadCategory();
// Arbitrary number of each of these
$this->loadAttributes();
$this->loadDocuments();
$this->loadFeatures();
$this->loadImages();
$this->loadVideos();
...
}
Каждый из методов нагрузки делает некоторые котла пластина, которая в конечном счете выполняет этот метод:
public function loadEntitiesByProductId($productId=0) {
// Get all the entities of this type that are associated with the product.
$entities = $this->entityManager
->getRepository($this->entityName)
->findByProduct($productId);
$instances = array();
// Create a Model for each entity and load the data.
foreach ($entities as $entity) {
$id = $entity->getId();
$instances[$id] = new $this->childClass();
$instances[$id]->entity = $entity;
$instances[$id]->loadValues();
}
return $instances;
}
Это нормально для случаев, когда связанный объект представляет собой отдельную таблицу, но обычно это сопоставление. В таких случаях я получаю все объекты сопоставления в первом запросе, тогда я должен запросить связанный объект в методе loadValues()
(через метод Doctrine get<Entity>()
). Результатом этого процесса является огромное количество запросов (часто> 100). Мне нужно избавиться от посторонних запросов, но я бы хотел сделать это, не теряя идиомы, которые я использую в своих моделях данных.
Есть ли способ заставить entityManager выполнять лучшую работу при использовании объединений для группировки этих запросов?
как о [экстра-ленивым] (http://docs.doctrine-project.org/en/2.0.x/tutorials/extra-lazy-associations.html) ассоциации? В Docs: «Ассоциации по умолчанию помечены как« Lazy », что означает, что весь объект коллекции для ассоциации заполняется при первом обращении к нему. Если вы отметите ассоциацию в качестве лишнего лени, можно вызвать следующие методы в коллекциях без запуска полной загрузки коллекции ' – manix