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

pog*_*ogo 21 doctrine-orm

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

$productionId = $performance->getProduction()->getId();
Run Code Online (Sandbox Code Playgroud)

在我确实只需要生产ID的情况下,发送另一个数据库查询来获取已经存在于某个对象中的值似乎是浪费.这有什么方法吗?

K. *_*ert 29

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

过时的答案如下:

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

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

你应该重写关联

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

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

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

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

$articleId = 1;
$article = $em->find('Article', $articleId);
$categoryId = $em->getUnitOfWork()->getEntityIdentifier($article->getCategory());
Run Code Online (Sandbox Code Playgroud)

即将推出2.2,你将能够使用IDENTITY DQL函数来选择一个外键,如下所示:

SELECT IDENTITY(u.Group) AS group_id FROM User u WHERE u.id = ?0
Run Code Online (Sandbox Code Playgroud)

已经致力于开发版本.

不过,你应该真的尝试坚持一种"正确"的方法.

  • 有许多用例,您只需要相关对象的ID.我认为为了性能调优,建议打破OOP概念.它最终只是一种不应该减慢你的应用程序的帮助.我很感激Noberts的解决方案,但不是他的概念立场. (3认同)