#join #symfony #doctrine #doctrine-orm
#Присоединиться #symfony #доктрина #doctrine-orm
Вопрос:
Я пытаюсь добиться некоторого повышения эффективности, объединив несколько записей из нескольких таблиц в соответствии со статьей: Присоединение к связанным записям. В моей модели у меня есть трекер, который имеет один набор ссылок, который, в свою очередь, имеет несколько ссылок. Теперь в моем контроллере я хочу перебирать эти ссылки через:
foreach ($tracker->getLinkset()->getLinks() as $link) etc..
Более того, код в моем репозитории Tracker выглядит следующим образом:
public function findWithLinks(Tracker $tracker)
{
$query = $this->createQueryBuilder('t')
->select('t, ls, l')
->innerJoin('t.linkset', 'ls')
->leftJoin('ls.links', 'l')
->where('t.id = :trackerId')
->setParameters(array(
'trackerId' => $tracker->getId()
));
return $query->getQuery()->getResult();
}
Чего я ожидал бы, так это того, что в контроллере, когда я перебираю таблицу foreach, Symfony не выполняет никаких дополнительных вызовов к базе данных, потому что у меня есть трекер с объединенным набором ссылок и объединенными ссылками. Однако для получения набора ссылок и ссылок по отдельности выполняются два дополнительных запроса. Вот сопоставления связанных объектов:
Объект Linkset:
/**
* @var Link
*
* @ORMManyToMany(targetEntity="Link", mappedBy="linkset")
*/
private $links;
Объект ссылки
/**
* @var Linkset
*
* @ORMManyToMany(targetEntity="Linkset", inversedBy="link")
* @ORMJoinTable(name="linkcombo",
* joinColumns={
* @ORMJoinColumn(name="link_id", referencedColumnName="id", onDelete="CASCADE")
* },
* inverseJoinColumns={
* @ORMJoinColumn(name="linkset_id", referencedColumnName="id", onDelete="CASCADE")
* }
* )
*/
private $linkset;
Ответ №1:
Может быть, вам следует изменить свой оператор «foreach» на что-то вроде этого?
foreach( $tracker->getLinkset() as $linkset ) {
foreach( $linkset->getLinks() as $link ) {
....
}
}
Я надеюсь, что это поможет!
Редактировать:
Если отношение между «linkset» и «link» является просто отношением manytomany, я бы изменил аннотации так, чтобы они выглядели следующим образом:
Объект linkset:
/**
* @ORMManyToMany(targetEntity="Link")
**/
private $links;
Объект ссылки:
/**
* @ORMManyToMany(targetEntity="Linkset")
*/
Это должно работать при условии, что:
- Объекты Link и Linkset используют одно и то же пространство имен, в противном случае вам следует изменить targetEntity=»XXX», чтобы оно было полным (т. Е. ВашBundle EntitiesLinkset и вашOtherBundle EntitiesLink
- Связь между трекером и набором ссылок в порядке (вы это проверили?)
Я уверен, что кто-то более опытный в symfony2 может помочь вам лучше, чем я, я недавно начал использовать symfony
Комментарии:
1. альгимо, спасибо за твой ответ, но, к сожалению, это, похоже, не работает. Это немного сбивает с толку, поскольку статья на веб-сайте Symfony предполагает, что это должно работать. Должно быть, я что-то упускаю из виду! 🙁
2. извините, я не взглянул на ваши объекты, я совершенно ясно видел, что проблема была в foreach. Я отредактирую свой комментарий другим предложением
3. Привет, Альгимо, спасибо за ваш ответ и ваши усилия. Но это тоже не работает. Если я удалю понятие ‘mappedBy=»linkset»‘, то Symfony2 пожалуется, что этот конкретный атрибут отсутствует. Есть другие идеи?