Doctrine部分查询返回完整对象(Doctrine partial queries return the complete object)

编程入门 行业动态 更新时间:2024-10-15 14:17:47
Doctrine部分查询返回完整对象(Doctrine partial queries return the complete object)

我正在尝试优化查询,因为我需要一个简单的列表作为一个附属于几个实体的实体。 所以我创建了这个查询,你应该只给我一个id和名字:

public function findAllOrderByName() { $qb = $this->createQueryBuilder('a'); $query = $qb->select(array('partial a.{id,name}')) ->addOrderBy('a.name', 'ASC') ->getQuery(); return $query->getResult(); }

像这样在控制器中返回它:

public function getInstrumentsAction() { $instruments = $this->getDoctrine()->getRepository('AcmeInstrumentBundle:Instrument')->findAllOrderByName(); return array('instruments' => $instruments); }

而不仅仅是让我回到两个阵营,给我完整的对象,因此包括其他相关实体的所有领域。

它为什么不起作用?

I'm trying to optimize the query as I need a simple list as an entity that is affiliated with several entities. So I created this query, you should just give me back the id and name:

public function findAllOrderByName() { $qb = $this->createQueryBuilder('a'); $query = $qb->select(array('partial a.{id,name}')) ->addOrderBy('a.name', 'ASC') ->getQuery(); return $query->getResult(); }

return it in the controller like this:

public function getInstrumentsAction() { $instruments = $this->getDoctrine()->getRepository('AcmeInstrumentBundle:Instrument')->findAllOrderByName(); return array('instruments' => $instruments); }

rather than just give me back the two camps, gives me the complete object, thus including all the fields of other related entities.

Why did not it work?

最满意答案

它实际上完全按照设计工作。 您观察的是您的相关实体的延迟加载。

首先添加:

echo $query->getSQL() . "\n"; return $query->getResult();

你会看到类似的东西:

SELECT p0_.id AS id0, p0_.name AS name1 FROM instrument p0_ ORDER BY p0_.name ASC

因此,只有您要求实际查询的两个字段。

echo sprintf("Instrument %s %s %s\n", $instrument->getName(),$instrument->getSomeotherScalervalue());

您将看到,虽然名称被回显,但是其他一些值甚至不在仪器表中。

就关系而言,让我们假设乐器与人之间有一种关系。

$persons = $instrument->getPersons();

你会期望$ people是一个空数组,但它实际上是一个相当聪明的Doctrine \ ORM \ PersistentCollection。 一旦你尝试用$ person做任何其他事情(即使是像count($ persons)一样简单的事情,也会触发另一个查询,并且所有链接的人物对象都将被加载。

这就是你所看到的。 您实际上可以在logs / dev.log中查看查询。 只要您拉入仪器,就只会生成一个查询。 一旦你尝试用关系做某事,另一个查询就会消失。

解决方法

不要试图访问关系。

在访问关系之前,您可以执行$ persons-> setInitialized(true); 这将阻止加载。 显然有点痛苦。

由于优化是您的目标,因此只返回一个数组结果。 根本没有任何对象。

您也可以继续在查询中加入您的关系,但使用partial来引入相关实体的id。 您的查询工作有点困难,但您不必担心会触发其他查询。

如果有一些方法可以在查询特定的基础上阻止延迟加载,那将会很好。 但如果有,我一直无法找到它。

It actually worked exactly as designed. What you are observing is the lazy loading of of your related entities.

Start by adding:

echo $query->getSQL() . "\n"; return $query->getResult();

You see something like:

SELECT p0_.id AS id0, p0_.name AS name1 FROM instrument p0_ ORDER BY p0_.name ASC

So only the two fields you asked for actually being queried.

echo sprintf("Instrument %s %s %s\n", $instrument->getName(),$instrument->getSomeotherScalervalue());

You will see that while name is echoed, some other value is not even though it's in the instrument table.

As far as relations go, let's suppose instrument has a oneToMany relation to persons.

$persons = $instrument->getPersons();

You would sort of expect $persons to be an empty array but it's actually a rather smart Doctrine\ORM\PersistentCollection. As soon as you try to do anything else with $person (even something as simple as count($persons) another query is triggered and all the linked person objects will get loaded.

So that is what you are seeing. You can actually see the queries in your logs/dev.log. As long as you just pull in the instrument then only one query is generated. As soon as you try to do something with a relation, another query goes out.

Work Arounds

Don't try to access relations.

Before accessing a relation you could do $persons->setInitialized(true); That will prevent loading. obviously a bit of a pain.

Since optimization is you goal then just return an array result. No objects at all.

You can also go ahead and join your relations in the query but use partial to just bring in say the id of the related entity. Your query works a bit harder but you won't need to worry about additional queries getting triggered.

It would be kind of nice if there was some way to prevent lazy loading on a query specific basis. But if there is, I have not been able to find it.

更多推荐

本文发布于:2023-07-28 06:42:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1301640.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:对象   完整   partial   Doctrine   complete

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!