Doctrine 2 - 急切加载似乎不适用于 ManyToMany

Doctrine 2 - Eager loading doesn't appear to work with ManyToMany

我有三个实体:SequenceRun 有一个 MaterialTypeString,还有很多 User。 IE。 SequenceRunMaterialTypeString之间存在一对多关系,SequenceRunUser之间存在多对多关系。

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 加载是否适用于多对多关系,还是我必须使用 DQL 并手动编写查询? (如果是的话那会是什么样子?)

你想达到什么目的?如果你想对你的 DB 进行单个查询,在其中获取所有需要的实体,你需要手动编写自定义查询,这不是急切或延迟加载的问题。

你可以这样写

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

当你希望 Doctrine 执行所有需要的查询时,无论你是否在代码中使用你的关联,你都使用预加载,而你使用延迟加载只有当你在你的代码中访问它们时才能让你的关联完全水合代码,但如果您在代码中访问所有关联,查询的数量将是相同的

重点是:
您显示的是分页的实体列表吗?然后,尝试使用 DQL 或查询构建器编写您自己的查询,根据您的观点获取加载所有必要的实体。
您显示的是单个实体吗?然后通过延迟加载关联从存储库中获取它,让 Doctrine 来完成这项工作!