原则2-渴望加载似乎不适用于ManyToMany [英] Doctrine 2 - Eager loading doesn't appear to work with ManyToMany

查看:98
本文介绍了原则2-渴望加载似乎不适用于ManyToMany的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个实体: SequenceRun 有一个 MaterialTypeString ,并且有许多 User 。即 SequenceRun MaterialTypeString 之间存在OneToMany关系,而 SequenceRun 之间存在ManyToMany关系。 code>和 User

I have three entities: SequenceRun has one MaterialTypeString, and has many User. I.e. There is a OneToMany relationship between SequenceRun and MaterialTypeString, and a ManyToMany relationship between SequenceRun and User.

SequenceRun.php:

SequenceRun.php:

/**
 * @ORM\ManyToOne(targetEntity="MaterialTypeStrings", inversedBy="sequenceRuns")
 * @ORM\JoinColumn(name="material_type_strings_id", referencedColumnName="id")
 */
private $materialTypeString;

 /**
  * Many Groups have Many Users.
  * @ORM\ManyToMany(targetEntity="FOSUser", mappedBy="sequenceRuns")
  */
 private $users;

现在无需急于加载我的索引方法:

Now without eager loading my index method:

/**
 * @Route("/sequence_run/index", name="sequence_run_index")
 */
public function indexAction() {
    // Grab all experiments from database and hand them to template.
    $repository = $this->getDoctrine()->getRepository('AppBundle:SequenceRun');
    $sequence_runs = $repository->findAll();
    return $this->render('sequence_run/index.html.twig',['sequence_runs' => $sequence_runs]);
}

针对单个 SequenceRun产生4个查询对象:

SELECT t0.username AS username_1, t0.username_canonical AS username_canonical_2, t0.email AS email_3, t0.email_canonical AS email_canonical_4, t0.enabled AS enabled_5, t0.salt AS salt_6, t0.last_login AS last_login_7, t0.confirmation_token AS confirmation_token_8, t0.password_requested_at AS password_requested_at_9, t0.roles AS roles_10, t0.id AS id_11, t0.dn AS dn_12, t0.cn AS cn_13, t0.department AS department_14, t0.department_dn AS department_dn_15, t0.from_bio_control AS from_bio_control_16, t0.password AS password_17 FROM fos_user t0 WHERE t0.id = ? LIMIT 1
Parameters: [0 => 96]

SELECT t0.id AS id_1, t0.start_date AS start_date_2, t0.end_dat AS end_dat_3, t0.kit AS kit_4, t0.run_coverage_target AS run_coverage_target_5, t0.read_length AS read_length_6, t0.created_at AS created_at_7, t0.updated_at AS updated_at_8, t0.material_type_strings_id AS material_type_strings_id_9 FROM sequence_run t0
Parameters: []

SELECT t0.username AS username_1, t0.username_canonical AS username_canonical_2, t0.email AS email_3, t0.email_canonical AS email_canonical_4, t0.enabled AS enabled_5, t0.salt AS salt_6, t0.last_login AS last_login_7, t0.confirmation_token AS confirmation_token_8, t0.password_requested_at AS password_requested_at_9, t0.roles AS roles_10, t0.id AS id_11, t0.dn AS dn_12, t0.cn AS cn_13, t0.department AS department_14, t0.department_dn AS department_dn_15, t0.from_bio_control AS from_bio_control_16, t0.password AS password_17 FROM fos_user t0 INNER JOIN users_sequence_runs ON t0.id = users_sequence_runs.fosuser_id WHERE users_sequence_runs.sequence_run_id = ?
Parameters: [0 => 2]

SELECT t0.id AS id_1, t0.type AS type_2 FROM material_type_strings t0 WHERE t0.id = ?
Parameters: [0 => 5]

如果我添加 fetch = EAGER MaterialTypeString ,它将删除最后一个查询(按预期方式)。但是,如果我也将其添加到 User ,我仍然会收到3个查询。

If I add fetch = "EAGER" to MaterialTypeString, it drops the last query (as expected). But if I add also add it to User I still get 3 queries.

是否需要渴望来处理ManyToMany关系,否则我将不得不使用 DQL 并手动编写查询? (如果是这样,那会是什么样?)

Does eager loading work for ManyToMany relationships, or will I have to use DQL and write the query manually? (If so what would that look like?)

推荐答案

您要实现什么目标?如果您希望针对自己的dB进行单个查询以获取所有需要的实体,那么您确实需要手动编写自定义查询,这与急切或延迟加载无关。

What are you trying to achieve? If you want to have a single query against your dB in which you fetch all the needed entities, you do need to write a custom query manually, it's not a matter of eager or lazy loading.

您可以这样写

$sequence_runs=$repository->createQueryBuilder('sr')->addSelect(['mts', 'fu'])
->leftJoin('sr.materialTypeString', 'mts')
->leftJoin('sr.users', 'fu')
->getQuery()->getResult();

无论您是否使用关联,当您希望教义进行所有需要的查询时,都可以使用预先加载是否使用代码,但是只有在您通过代码进行访问时才使用延迟加载使关联完全被水化,但是如果您访问代码中的所有关联,查询的次数将相同。

You use eager loading when you want doctrine to do all the needed queries no matter if you use your associations in your code or not, while you use lazy loading to have your associations fully hydrated only if you access them in your code, but the number of queries will be the same in case you access all your associations in your code.

要点是:您是否正在显示实体的分页列表?然后,尝试使用DQL或查询构建器编写您自己的查询,并根据您的视图获取加载所有必需的实体。您是否显示一个实体?然后,从懒惰地从存储库中获取它并加载您的关联,然后让doctrine完成这项工作!

The point is: are you showing a paginated list of entities? Then, try to write your own query with DQL or a query builder, fetch loading all the necessary entities in reason of your views. Are you showing a single entity? Then fetch it from the repository lazy loading your associations and let doctrine do the job!

这篇关于原则2-渴望加载似乎不适用于ManyToMany的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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