我有三个实体:SequenceRun
有一个MaterialTypeString
,并且有很多User
。即SequenceRun
和MaterialTypeString
之间存在OneToMany关系,SequenceRun
和User
之间存在ManyToMany关系。
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;
现在没有急于加载我的索引方法:
/**
* @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个查询。
eager
加载是否适用于ManyToMany关系,还是我必须使用DQL
并手动编写查询? (如果是这样的话会是什么样的?)
答案 0 :(得分:1)
你想要达到什么目的?如果您希望针对dB获取所有需要的实体的单个查询,则需要手动编写自定义查询,这不是急切或延迟加载的问题。
你可以写这样的东西
$sequence_runs=$repository->createQueryBuilder('sr')->addSelect(['mts', 'fu'])
->leftJoin('sr.materialTypeString', 'mts')
->leftJoin('sr.users', 'fu')
->getQuery()->getResult();
如果您希望教义执行所有必需的查询,无论您是否在代码中使用关联,都使用急切加载,而使用延迟加载只有在代码中访问它们时才能使关联完全保持水分,但是如果您访问代码中的所有关联,查询的数量将是相同的。
重点是:您是否显示了实体的分页列表?然后,尝试使用DQL或查询构建器编写自己的查询,根据您的视图获取加载所有必需的实体。你在展示一个实体吗?然后从存储库中取出它,延迟加载你的关联,并让doctrine完成这项工作!