Ответ 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
Он уже уже внесен в версии разработки.
Тем не менее, вы действительно должны пытаться придерживаться одного из "правильных" методов.