首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nette框架- Nette\Database\ResultSet只实现单向迭代器

Nette框架- Nette\Database\ResultSet只实现单向迭代器
EN

Stack Overflow用户
提问于 2020-10-31 16:47:13
回答 1查看 490关注 0票数 1

我遇到了一个与弗勒奇有关的问题。如果在第一个foreach {foreach $children as $child}中返回一个结果,那么它就能工作。由于有更多的错误,会弹出一个错误:Nette\Database\ResultSet只实现单向迭代器。

错误可能是由第一个($children)和第二个($invoices)在同一个表childern中查询引起的。我需要列出所有的孩子(如$child->firstName),并分配项目给每个(如$invoice->date $invoice->snackName)。但是,我不能取消查询中的"JOIN ON children“。

输出:

儿童1名

  • 项目1
  • 项目2

子2名

  • 项目1
  • 项目2

不知道怎么回事?谢谢

代码语言:javascript
复制
public function actionShow($year, $month)
 {
    $invoices = $this->database->query('
    SELECT
        o.date AS date,
        o.snack AS snack
    FROM
        diet_orders o
    LEFT JOIN children ch ON o.child_id = ch.id
    WHERE
        ch.user_id = ?
        and YEAR (o.date) = ?
        and MONTH (o.date) = ?
            ', $this->getUser()->id, $year, $month,'');
            $children = $this->database->table('children')->where('user_id = ?', $this->getUser()->id);
    
    $this->template->invoices = $invoices;
    $this->template->children = $children;
}

拿铁

代码语言:javascript
复制
{block content}
{foreach $children as $child}
{$child->fisrtName}
    {foreach $invoices as $invoice}
      {invoice->snack}
     {/foreach}
{/foreach}

{/block}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-31 20:55:01

你的推理是正确的。大多数ResultSet方法返回的Nette\Database是一个单向迭代器,因此您不能在一个循环体的多次执行中使用它。这是一种优化--一旦循环推进迭代器,前一行可能会被垃圾收集,这对于在大型数据库表上节省内存很有用。

如果确实需要对表进行多次迭代,则可以:

  • 多次创建$invoices
    • 可能将整个赋值移动到模板内的循环中。
    • 或者创建返回结果并在模板中调用它的函数。

  • 或者将整个ResultSet加载到内存中,例如将其转换为数组。这也是文档所建议的:在ResultSet上只能迭代一次,如果我们需要多次迭代,就必须通过fetchAll()方法将结果转换为数组。

但是如果可能的话,最好的解决方案是将其修复为使用JOIN。如果在数据库中使用FOREIGN KEYS,则可以避免编写原始SQL,并在尝试通过具有外键约束的列访问其他表的数据时,使用更好的界面为您透明和高效地创建JOIN

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64624165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档