Doctrine2 一对一关系自动加载查询 [英] Doctrine2 one-to-one relation auto loads on query

查看:17
本文介绍了Doctrine2 一对一关系自动加载查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似这样的查询:

I have a query that looks like this:

我的用户实体具有如下所示的一对一关系:

My user entity has a one-to-one relation that looks like this:

/**
 * @var UserProfile
 *
 * @ORMOneToOne(targetEntity="UserProfile",mappedBy="user")
 */
private $userProfile;

每当我查询以选择多个用户对象时,它都会为每个用户创建一个额外的选择语句来查询 UserProfile 数据,即使我没有通过 get 方法访问它.我并不总是需要 UserProfile 数据,而且我当然不想每次显示用户列表时都加载这些数据.

Anytime I make a query to select multiple user objects, it creates an additional select statement per user to query for the UserProfile data even though I am not accessing it through a get method. I don't always need the UserProfile data, and I certainly don't want to load this data every single time I'm displaying a list of users.

知道为什么在运行时执行这些查询吗?

Any idea why these queries are executed at run time?

推荐答案

这里是解决方案的详细解释:

Here is solutions explain with details :

https://groups.google.com/forum/#!topic/doctrine-user/fkIaKxifDqc

映射中的fetch"是一个提示,也就是如果有可能Doctrine 做到了这一点,但如果它不可能,显然它不会.从技术上讲,代理延迟加载并不总是可行的.不可能的情况是:

"fetch" in the mapping is a hint, that is, if it is possible Doctrine does that, but if its not possible, obviously it does not. Proxying for lazy-loading is simply not always possible, technically. The situations where its not possible are:

1) 从逆到拥有方的一对一(只出现在双向一对一关联).前提 a) 以上不能见面.2) 一对一/多对一关联到层次结构和目标类有子类(不是类层次结构中的叶子).不能满足上述前提b).

1) one-to-one from inverse to owning side (appears only in bidirectional one-to-one associations). Precondition a) above can not be met. 2) one-to-one/many-to-one association to a hierarchy and the targeted class has subclasses (is not a leaf in the class hierarchy). Precondition b) above can not be met.

在这些情况下,代理在技术上是不可能的.

In these cases, proxying is technically not possible.

避免此 n+1 问题的选项:

Your options to avoid this n+1 problem:

1) 通过 DQL 获取连接:select c,ca from Customer join c.cart ca".单个查询但加入,但是,对一关联的加入是相对便宜.

1) fetch-join via DQL: "select c,ca from Customer join c.cart ca". Single query but join, however, joins on to-one associations are relatively cheap.

2) 强制部分对象.没有额外的查询,但也没有延迟加载: $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD,真的)

2) force partial objects. No additional queries but also no lazy-load: $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)

3) 如果替代结果格式(即 getArrayResult())是对于用例来说足够了,这些也避免了这个问题.

3) if an alternative result format (i.e. getArrayResult()) is sufficient for a use-case, these also avoid this problem.

Benjamin 对这些负载的自动批处理有一些想法避免 n+1 查询,但这不会改变代理是并不总是可能的.

Benjamin had some ideas about automatic batching of these loads to avoid n+1 queries but this does not change the fact that proxying is not always possible.

这篇关于Doctrine2 一对一关系自动加载查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆