你可以从Doctrine2中的对象获取外键而不加载该对象吗?

时间:2011-11-21 12:19:53

标签: doctrine-orm

我正在制作一个活动网站,并且在制作和表演之间有一对多的关系,当我有一个表演对象时,如果我需要它的制作ID,我必须这样做

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

如果我确实需要生产ID,那么发送另一个数据库查询来获取某个已经存在于某个对象中的值似乎是浪费。 有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:29)

编辑2013.02.17:
我在下面写的不再是真的。 您不必在问题中概述的方案中做任何事情,因为Doctrine足够聪明地将id字段加载到相关实体中,因此代理对象已经包含id,它将会不发出对数据库的另一个调用。

下面的过时答案:

这是有可能的,但没有得到修改。

背后的原因是,Doctrine试图真正坚持你的实体应该形成一个对象图的原则,外键没有位置,因为它们只是“工件”,来自关系数据库的工作方式

您应该将关联重写为

  • 渴望加载,如果您总是需要相关实体
  • 编写DQL查询(最好在存储库中)以获取加入相关实体
  • 通过在其上调用getter来让它延迟加载相关实体

如果你不相信,并且真的想要避免以上所有,那么有两种方法(我知道),获取相关对象的id,不会触发负载,也不会诉诸于反思和序列化:

如果您已拥有该对象,则可以检索Doctrine在内部使用的内部UnitOfWork对象,并使用它的getEntityIdentifier()方法,将其传递给卸载的实体(代理对象)。它将返回id,而不会触发延迟加载。

假设您有多对一关系,多篇文章属于某个类别:

$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

开发版本为already committed

尽管如此,你应该坚持使用其中一种“正确”的方法。