2016-01-15 2 views
5

Если у вас есть набор ассоциативно связанных объектов в Doctrine, иногда вам может понадобиться получить эти объекты без сопоставления сопоставленных ассоциаций и замедления запроса вниз.Как получить объекты без их сопоставления ассоциаций в Doctrine 2

Например, у меня есть набор объектов, которые являются ассоциациями, отображаемыми в цепочке связанных таблиц базы данных. Все они являются ассоциациями OnetoMany и действуют как иерархия цен в матрицах на страницах продуктов. Они могут быть представлены в виде так:

SitePage->SiteMatrix->SiteItems->SiteItemPrices. 

Связанная отображение прекрасно работает, и когда я использую метод findBy, чтобы получить корневой SitePage объект содержит массивы, которые представляют собой преобразованные объекты вниз по цепочке. Другими словами, объект SitePage содержит все матрицы, содержащие все элементы, содержащие все цены. Все идет нормально.

Моя проблема заключается в том, что каждый раз, когда я получаю список страниц на своем сайте, доктрина идет по всему дереву сопоставления ассоциации и возвращает меня со всей необходимой базой данных, которая очень медленная. Когда-нибудь я хочу просто получить объект SitePage по ID и не содержать всех сопоставленных ассоциаций.

Я посмотрел в ленивую и дополнительную отложенную загрузку ассоциаций, но они, кажется, только воздействуют на определенные функции, а не findBy и т.д. Официальная документация далека от полезного: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html

Других подобные вопросы на переполнении стека есть не принимаются: Doctrine 2 Association Mapping Overhead?

Есть ли простой способ получить объект без сопоставленных ассоциаций? Самый простой способ, который я вижу в настоящее время, - создать два объекта для каждой таблицы базы данных: один с сопоставлением ассоциаций и один без использования в отдельных ситуациях, где они необходимы. Мне кажется странным, что вы не можете просто получить сущность и указать, хотите ли вы привязать ее к другим объектам или получить ее самостоятельно.

Благодарим за любую информацию по этому вопросу.

+0

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

+0

Спасибо за ваш ответ, но эта проблема уже более года. Оказалось, что я использовал сериализатор для сериализации моих объектов в массивы, и именно этот сериализатор вызывал каждую функцию getter в дереве сопоставления ассоциаций. Как только я узнал об исключениях, максимальной глубине и функциональности групп в комплекте JMS Serializer, все стало ясно, и я смог использовать связь с гораздо большим контролем. – Asq

ответ

2

Стратегии исключения JMSSerializer могут помочь вам.

Во-первых, исключить все свойства по умолчанию:

// ... 

use JMS\Serializer\Annotation as JMS; 

/** 
* @ORM\Entity 
* @JMS\ExclusionPolicy("all") 
*/ 
class Foo 

Затем выберите, чтобы исключить или выставить свои свойства:

/** 
* @ORM\Column(type="string") 
* @JMS\Expose 
*/ 
protected $name; 

Кроме того, для ассоциаций, вы можете использовать MaxDepth может запретить связанные с вашими результатами. Пример:

// Entity 
/** @MaxDepth(1) */ 
private $selfAssociatedEntries; 

// Controller 
use JMS\Serializer\SerializationContext; 

$serializer->serialize($data, 'json', SerializationContext::create()->enableMaxDepthChecks()); 

Подобно этому, ваша организация будет содержит $selfAssociatedEntries сериализован, но $selfAssociatedEntries не имеет $selfAssociationEntries свойство.
Сериализация ограничена первым родительским объектом.

Groups являются мощная функция, которая позволяет выставить свойства некоторых действий и исключить их для другого:

/** 
* @ORM\Column(type="string", length=255, nullable=true, unique=false) 
* @JMS\Groups({"default"}) // Set the group to expose the property 
*/ 
protected $name; 

В контроллере установите группу, используемую для сериализации:

// Property 'name' is exposed 
$serializer->serialize($data, 'json', SerializationContext::create()->setGroups(array('default'))); 

Для больше информации, посмотрите на Exclusion Strategies глава документации.

+0

Благодарим вас за разъяснение этой концепции. Использование стратегий исключения JMSSerializer делает привязку ассоциации doctrine очень мощным инструментом. Официальные документы для ссылок - http://jmsyst.com/libs/serializer/master/cookbook/exclusion_strategies – Asq

+0

Добро пожаловать, благодарю вас за ваше терпение. Если у вас есть лучшее объяснение maxDeprh, не стесняйтесь говорить мне, и я улучшу свое. – chalasr

+0

Это все хорошо, но влияет ли это на основной запрос ?, это презентация, запрос все равно должен произойти правильно? –