Doctrine2 预先加载运行多个查询而不是 1

Dop*_*yNL 5 eager-loading symfony doctrine-orm

我将 Symfony2 与 Doctrine2(最新版本)一起使用,并定义了这种关系:

/**
 * @ORM\OneToMany(targetEntity="Field", mappedBy="event", fetch="EAGER")
 * @ORM\OrderBy({"name" = "ASC"})
 */
protected $fields;
Run Code Online (Sandbox Code Playgroud)

关系的另一边定义为:

/**
 * @ORM\ManyToOne(targetEntity="Event", inversedBy="fields", fetch="EAGER")
 * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
 */
protected $event;
Run Code Online (Sandbox Code Playgroud)

在执行“fetchOnyById”时,Doctrine 运行 2 个查询。1 获取对象本身,1 获取相关字段。我希望这是一个连接,但它不是。

在控制器中完成后,我将对象传递给树枝。在那里我再次检索字段作为对象的属性。这会导致运行另一个查询以再次检索字段。

Clearly I'm doing something wrong, as I would expect only 1 query to be run and 3 are actually run.

Moy*_*lin 3

我相信发生这种情况的原因是因为您正在获取实体,而不是特定的查询。Doctrine 的想法是,您正在获取对象,而不是与数据库交互,而是与对象资源交互,就好像它们都像存储的实体一样关联/引用。如果您需要像您所描述的那样的查询,那么最好使用 DQL,但此时您不会获取创建的实体,而是会获得自定义结果。

我希望这是有道理的。

基本上,您使用的默认关联是获取关联对象而不是联接查询。

  • 基本上这就是 Doctrine2 中急切加载的工作原理。相关对象的单独查询在该对象的第一个查询之后运行。那么急切加载的使用比我想象的要少一些,通常最好使用延迟加载。在特殊情况下,联接可能很有用,但这将是存储库中运行自定义查询的额外方法。基本上:我对这种行为的期望是错误的。恩克斯! (3认同)