43

Assume I've an entity, which references itself to map 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;

I have a use case where I want to get food_group_id of an entity without getting full parent object from database. Using fetch="LAZY" doesn't keep Doctrine from querying again. Is there a way to return only the ID when getting $food->getFoodGroup()?

4

4 回答 4

108

不要让你的生活复杂化,你可以做到

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

不会执行任何额外的查询或触发延迟加载!

为什么?因为你$food->foodGroup是一个知道它的 ID 的代理对象。如果您调用某个尚未加载的字段的 getter 方法,它只会执行延迟加载。

于 2013-10-02T20:59:15.723 回答
5

您应该能够定义 ID 字段,将其与 ORM 关联,​​然后为该字段创建 getter,它应该可以工作。

/**
 * @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 关联映射似乎很奇怪。我不确定为什么您在实体上可以为​​空(我以前从未见过)。您没有referencedColumnName="id",但也许这只是因为它默认为“id”(我喜欢明确)。请参阅教义文档

我有一个非常相似的问题,这是因为我没有将该字段与 ORM 相关联。所以你应该知道可以调用:

$food = $em->getRepository("AcmeFoodBundle:Food")->find($id);
$food->getFoodGroupId();
于 2014-05-13T20:32:47.943 回答
4

您可以使用

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

在不加入的情况下获得 id。

在您的示例中,它将是这样的:

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

这样,您无需额外加入即可获得 food_group_id。

于 2013-10-02T16:31:37.403 回答
-1

我不确定这是否是一个性能问题,并且您正在尝试限制查询,但为什么不在您的 getter 中执行类似的操作(我假设这是您使用 Doctrine ORM Annotations 的 Food 实体):

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

        return $foodGroup->getId();
    }

甚至更好地命名它getFoodGroupId()

于 2013-10-02T15:43:05.843 回答