Doctrine2: заполнить связанные сущности после загрузки основной - PullRequest
1 голос
/ 10 августа 2011

Есть HotelComment и CommentPhoto (1: n) - пользователь может добавить несколько фотографий в свой комментарий. Я загружаю часть комментариев одним запросом и хочу загрузить фотографии к этим комментариям, используя другой запрос (используя WHERE IN).

$comments = $commentsRepo->findByHotel($hotel);
$comments->loadPhotos(); // of course comments is simple array yet

Загрузка комментариев необходима по запросу, а не на PostLoad мероприятии.

Так что вопрос: как можно связать загруженные комментарии с объектами HotelComment? Использование ReflectionProperty: setAcesseble() + setValue()? Есть ли более простое решение? И я боюсь, что UoW обнаружит HotelComment сущности как измененные и отправит обновления в базу данных.

Ответы [ 2 ]

0 голосов
/ 11 августа 2011

Если вы хотите гидрировать связанные объекты только один раз, а не каждый раз, когда объект загружается, вам нужно использовать DQL:

$em->createQuery("SELECT comments, photos FROM HotelComment comments JOIN comments.photos photos");

Вы можете поместить это в метод в хранилище,Это выдаст один оператор SELECT с INNER JOIN к таблице фотографий с комментариями.

0 голосов
/ 11 августа 2011

Вы должны настроить ваше отношение как "Ленивый". Смотрите документацию к доктрине:

  1. ManyToOne
  2. ManyToMany
  3. OneToOne

Чем вы сможете его лениво загрузить с помощью $comments->loadPhotos(), по крайней мере, документация так говорит

ОБНОВЛЕНИЕ: Я думаю, вам не нужно делать что-то особенное, чтобы избежать сброса ваших сущностей в БД. Фактически, когда вы запрашиваете ваши записи с помощью DQL, они имеют состояние managed, поэтому их присоединение к коллекции другого управляемого объекта не меняет их состояния, поэтому они не сбрасываются, если вы не изменили их.

Но это совсем не помогает, потому что ассоциации извлекаются до первого использования, поэтому добавление объекта в коллекцию с помощью следующего кода приведет к неявному запросу базы данных:

$comment->addPhoto($photo);
//in Comment class
function addPhoto(Photo $photo){
    //var_dump(count($this->photos)); //if you have any - they are already here
    $this->photos->add($photo);
}

Возможно, если объявить вашу коллекцию общедоступной (или этот трюк с ReflectionProperty) поможет обмануть Доктрину, но это грязный хак, поэтому я даже не пробовал их.

Отключение родительской сущности также не помогает. У меня пока нет идей ...

...