Symfony2 自定义存储库、延迟加载和代理对象

发布于 2024-12-12 00:39:57 字数 1101 浏览 0 评论 0原文

我在使用 Symfony2 中的 Doctrine2 从数据库中提取相关对象时遇到一些问题。我有一个具有以下功能的自定义存储库:

public function getOrder($id) {
    $DQL = 'SELECT request, orderer
    FROM OrderRequestBundle:OrderRequest request
    JOIN request.orderer orderer
    WHERE request.id = :id';

    $query = $this->getEntityManager()->createQuery($DQL)
                ->setParameter('id', $id)
                ->setMaxResults(1);
    return $query->getResult();
}

...但是由于某种原因,当我运行此函数时,我返回了 OrderRequest 对象的代理对象,而不是 OrderRequest 的真实实例,我是否遗漏了什么?看来 Doctrine2 喜欢延迟加载,而我似乎无法让它摆脱困境并为我获取对象。

更新: 我试图简单地使用以下代码在 Twig 模板中显示信息:

$order = $this->getDoctrine()
    ->getRepository('OrderRequestBundle:OrderRequest')
    ->getOrder($id);

return $this->render('OrderRequestBundle:Admin:view.html.twig', array('order' => $order));

其中 Twig 如下调用有关“order”变量的信息:

{{ order.quantity }}

...但我最终遇到了此错误:

Item "quantity" for "Array" does not exist in "OrderRequestBundle:Admin:view.html.twig" at line 5

I'm having some trouble pulling up relationed objects from my database using Doctrine2 in Symfony2. I have a custom repository with the following function:

public function getOrder($id) {
    $DQL = 'SELECT request, orderer
    FROM OrderRequestBundle:OrderRequest request
    JOIN request.orderer orderer
    WHERE request.id = :id';

    $query = $this->getEntityManager()->createQuery($DQL)
                ->setParameter('id', $id)
                ->setMaxResults(1);
    return $query->getResult();
}

...but for some reason when I run this function I get back a Proxy object for an OrderRequest object rather than a real instance of OrderRequest, am I missing something? It seems that Doctrine2 loves lazy-loading and I can't seem to get it up off its ass and fetch objects for me.

UPDATE:
I'm attempting to simply display the information in a Twig template with the code below:

$order = $this->getDoctrine()
    ->getRepository('OrderRequestBundle:OrderRequest')
    ->getOrder($id);

return $this->render('OrderRequestBundle:Admin:view.html.twig', array('order' => $order));

Where Twig calls information about the 'order' variable as so:

{{ order.quantity }}

...but I just end up with this error:

Item "quantity" for "Array" does not exist in "OrderRequestBundle:Admin:view.html.twig" at line 5

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

枕花眠 2024-12-19 00:39:57

更新

根据您的编辑,问题根本不是代理对象,而是您使用 $query 对象的方式。

$query->getResult() 将返回结果数组。在这样的实例中,您将结果集限制为最多 1 行,它将返回一个包含一个条目的数组,但仍然是一个数组。当 Twig 尝试使用访问器方法时,自然会对此感到窒息。

您需要做的是使用 $query->getSingleResult() 来代替。请注意,如果查询返回多于一行,Doctrine 将抛出一个非唯一结果异常,因此您需要确保将它与 setMaxResults(1) 一起使用,就像您正在做的那样,如果查询可以可能返回多个结果。

结束更新

来自参考文档代理

这里的$item实际上是代理类的一个实例
为 Item 类生成,但您的代码不需要关心。在
事实上它不应该关心。代理对象应该对您透明
代码。

强调他们的。代理应该对您的代码透明,并尽可能提高性能;但是,如果您迫切需要急切加载部分查询,则可以在实体配置文件中设置获取模式,或者查看 文档的此部分

$query = $em->createQuery("SELECT u FROM MyProject\User u");
$query->setFetchMode("MyProject\User", "address", "EAGER");
$query->execute();

UPDATE

Given your edit, the problem isn't proxy objects at all, it's how you're using your $query object.

$query->getResult() will return an array of results. In an instance like this where you're limiting the result set to a max of 1 row, it'll return an array with one entry, but still an array. Twig chokes on this when trying to use accessor methods, naturally.

What you'll want to do is use $query->getSingleResult() instead. Note that Doctrine will throw a non-unique result exception if the query returns more than one row, so you need to be sure to use it with setMaxResults(1) like you're doing if the query can possibly return multiple results.

END UPDATE

From the documentation on reference proxies:

Here $item is actually an instance of the proxy class that was
generated for the Item class but your code does not need to care. In
fact it should not care. Proxy objects should be transparent to your
code.

Emphasis theirs. Proxies should be transparent to your code, and exist to improve performance where possible; however, if you have a pressing need to eager-load part of the query, you can either set the fetch mode in your entity configuration file, or check out this section of the docs:

$query = $em->createQuery("SELECT u FROM MyProject\User u");
$query->setFetchMode("MyProject\User", "address", "EAGER");
$query->execute();
寒尘 2024-12-19 00:39:57

Doctrine2总是从存储库查询返回代理对象。这些扩展了您的实体类,并且出于所有意图和目的,都是同一件事。

代理只是使您的实体能够支持相关实体的延迟加载(除其他外)。

请参阅 http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html?highlight=proxy#entity-object-graph-traversal

Doctrine2 always returns proxy objects from repository queries. These extend your entity classes and for all intents and purposes, are the same thing.

The proxies simply enable your entities to support lazy-loading of related entities (among other things).

See http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html?highlight=proxy#entity-object-graph-traversal

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文