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

Получение только идентификатора из отношений сущностей без извлечения всего объекта в Доктрине

Предположим, у меня есть сущность, которая ссылается на карту parent-child-relations

class Food
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Food", inversedBy="foodChildren")
     * @ORM\JoinColumn(name="food_group_id", nullable=true)
     */
    protected $foodGroup;

    /**
     * @ORM\OneToMany(targetEntity="Food", mappedBy="foodGroup", fetch="LAZY", cascade={"remove"})
     */
    protected $foodChildren;

У меня есть случай, когда я хочу получить food_group_id объекта без получения полного родительского объекта из базы данных. Использование fetch="LAZY" не возвращает Doctrine из запроса. Есть ли способ вернуть только ID при получении $food->getFoodGroup()?

4b9b3361

Ответ 1

Не усложняйте свою жизнь, вы можете просто сделать

$food->getFoodGroup()->getId()

Этот НЕ БУДЕТ выполнять любой дополнительный запрос или запускать ленивую загрузку!

Почему? Потому что ваш $food->foodGroup - это прокси-объект, который знает об этом ID. Это будет выполнять только ленивую нагрузку, если вы вызываете метод getter некоторого поля, которое не было загружено.

Ответ 2

Вы можете использовать

$em->getUnitOfWork()->getEntityIdentifier(...);

чтобы получить идентификатор без создания объединений.

В вашем примере это будет примерно так:

$em = $this->getDoctrine()->getManager();
$food = $em->getRepository('HungryHungryBundle:Food')->findOneById($id);
print_r($em->getUnitOfWork()->getEntityIdentifier($food->getFoodGroup())); 
die();

Таким образом вы получите файл food_group_id без дополнительного подключения.

Ответ 3

Вы должны иметь возможность определить поле идентификатора, связать его с ORM, а затем создать геттер для этого поля, и он должен работать.

/**
 * @ORM\ManyToOne(targetEntity="Food", inversedBy="foodChildren")
 * @ORM\JoinColumn(name="foodGroupId", referencedColumnName="id")
 */
protected $foodGroup;

/**
 * @ORM\Column(type="integer")
 */
protected $foodGroupId;

public function getFoodGroupId() {
    return $this->foodGroupId;
}

Заметьте, я изменил имя поля в моем примере на Pascal Case для согласованности. Кроме того, я новичок в Symfony, но ваше сопоставление ассоциаций ManyToOne кажется странным. Я не уверен, почему у вас есть значение nullable для объекта (я этого раньше не видел). У вас нет ссылочного столбцаName = "id", но, возможно, это просто потому, что по умолчанию он "id" (мне нравится быть явным). См. Doctrine docs.

У меня была очень похожая проблема , которая была вызвана только потому, что я не связал это поле с ORM. Поэтому вы должны знать, что можно позвонить:

$food = $em->getRepository("AcmeFoodBundle:Food")->find($id);
$food->getFoodGroupId();

Ответ 4

Я не уверен, что это проблема производительности, и вы пытаетесь ограничить запросы, но почему бы просто не сделать что-то подобное в своем getter (я предполагаю, что ваш объект Food с использованием Doctrine ORM Annotations):

class Food
{
    ...
    public function getFoodGroup() {
        $foodGroup = $this->getFoodGroup();

        return $foodGroup->getId();
    }

или даже лучше назовите его соответствующим образом getFoodGroupId()