【问题标题】:Fatal error in Yii immediately after adding eager-loading添加急切加载后立即在 Yii 中出现致命错误
【发布时间】:2012-07-06 04:25:55
【问题描述】:

我有 3 个CActiveRecord 模型:

  • 一个
  • B
  • C

关系:

  • A 有很多 B。
  • A 有很多 C。
  • B 属于 A。
  • C 属于 A。

AControlleractionHome($id) 中,我正在从数据库中检索A 的单行。就像默认的actionView($id)一样。

在我的actionHome() 视图中,我还列出了属于ABC 的所有实例。

public function actionHome($id)
{
  $this->render('home', array('a' => A::model()->findByPk($id)));
}

actionHome() 中,我想使用A 的关系的急切加载

但是,当我将with() 添加到findByPk() 函数时,我立即得到一个致命错误。

public function actionHome($id)
{
  $this->render('home', array('a' => A::model()->with('bs','cs')->findByPk($id)));
}

Fatal error: Call to a member function label() on a non-object in我的home.php查看文件。

label() 是我的 A 模型类中的一个公共静态函数。

所以,由于我添加了即时加载,这会导致该功能不可用。

有人可以帮忙吗?
为什么这个功能不再可用?

label() 在我的视图中调用 home.php,如下所示:

$this->breadcrumbs = array(
  CHtml::encode($a->label(2)) => array('index'),
  CHtml::encode($a->name),
);

label() 在我的模型中定义如下:

public static function label($n = 1) 
{
  if ( $n == 0 ) $n = 1;
  return Yii::t('app', 'A|As', $n);
}

如果我在视图中注释掉对label() 的调用(或将调用更改为A::label(2)),那么下一行也会触发一个错误,..“名称”不是非属性-对象。

显然,出于某种原因,$a 不再是一个对象。

更新 1:

添加with() 导致findByPk($id) 返回NULL,因此$a 在我看来是NULL,所以我试图找出原因。延迟加载没有这个问题。

【问题讨论】:

  • 我的模型上的默认范围是否与返回 NULL 有关?我不确定为什么延迟加载和急切加载会有所不同。
  • 你为什么不打开日志,看看正在执行哪些查询,这样调试会变得更容易
  • 为什么将withfindByPk 一起使用? with 仅在相关表中有条件时才有用,但 findBYPk 仅在一个表上搜索主键。
  • 你的模型 A 肯定是空的。
  • @Örs 也许我不太理解with。我正在处理的视图目前正在执行 70 个查询。用户转到example.com/a/home/1 以查看属于其A 的所有BC 实例。我认为无论用户的“A”有多少BC 实例,整个视图都应该能够加载最多7 个查询。我认为我在视图中的foreach 循环会为BC 的每次迭代触发额外的3 个查询。我希望with 会提前加载所有内容。

标签: php yii eager-loading


【解决方案1】:

findByPk() 正在返回 NULL,因为关系 cs 为空。 Yii 正在做一个从ABINNER JOIN,因为没有属于AB,结果集是空的。

延迟加载没有这个问题,因为它在需要来自B 的数据之前不会进行查询。

【讨论】:

  • 也就是说,即使使用with(),视图仍在执行 70 次查询。我一定不明白with() 的使用或如何正确进行急切加载。我觉得只是做一个手动 SQL 查询。
  • 您应该先阅读文档,然后再执行其他操作。
猜你喜欢
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 2020-08-01
  • 2020-01-13
相关资源
最近更新 更多