Подтвердить что ты не робот

Можете ли вы получить внешний ключ от объекта в Doctine2 без загрузки этого объекта?

Я работаю над сайтом событий и поддерживаю отношения "один-много" между производством и его исполнением, когда у меня есть объект производительности, если мне нужен его производственный идентификатор в настоящий момент, когда я должен делать

$productionId = $performance->getProduction()->getId();

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

4b9b3361

Ответ 1

Изменить 2013.02.17:
То, что я написал ниже, уже не так. Вам не нужно ничего делать в сценарии, описанном в вопросе, потому что Doctrine достаточно умна, чтобы загружать поля id в связанные объекты, поэтому объекты-прокси уже будут содержать идентификатор, и это будет не выдавать другой вызов в базу данных.

Устаревший ответ ниже:

Возможно, но это не рекомендуется.

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

Вы должны переписать ассоциацию как

  • загружается, если вам всегда нужен связанный объект
  • напишите DQL-запрос (желательно в репозитории) для извлечения-соединения связанного объекта
  • пусть lazy-load связанный объект, вызвав геттер на нем

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

Если у вас уже есть объект в руке, вы можете получить внутренний UnitOfWork объект, который Doctrine использует внутри, и использовать метод getEntityIdentifier(), передавая его выгруженный объект (прокси-объект). Он вернет вам идентификатор, не запуская ленивую нагрузку.

Предполагая, что вы имеете отношение "много-к-одному", с несколькими статьями, относящимися к категории:

$articleId = 1;
$article = $em->find('Article', $articleId);
$categoryId = $em->getUnitOfWork()->getEntityIdentifier($article->getCategory());

Приступая к 2.2, вы сможете использовать функцию IDENTITY DQL, чтобы выбрать только внешний ключ, например:

SELECT IDENTITY(u.Group) AS group_id FROM User u WHERE u.id = ?0

Он уже уже внесен в версии разработки.

Тем не менее, вы действительно должны пытаться придерживаться одного из "правильных" методов.