【问题标题】:Yii2 - Calling model functions on entire activeRecords?Yii2 - 在整个 activeRecords 上调用模型函数?
【发布时间】:2017-07-11 19:44:16
【问题描述】:

我要做什么

我想像这样使用主动模型查询一组特定的记录

$jobModel = Jobs::find()->select('JOB_CODE')->distinct()->where(['DEPT_ID'=>$dept_id])->all();

然后我想根据是否出现在关系表中,给这个activerecord中的记录分配一个flag属性

我的尝试

所以在我的工作模型中,我声明了一个新属性inAccount。然后我在作业模型中添加了这个函数,根据是否在关系表中找到具有指定account_id 的记录,将inAccount 标志设置为-1 或0。

public function assignInAccount($account_id){
    if(JobCodeAccounts::find()->where(['JOB_CODE'=>$this->JOB_CODE])->andWhere(['ACCOUNT_ID'=>$account_id])->one() == null){
        $this->inAccount=0;
    }
    else{
        $this->inAccount = -1;
    }
}

我一直在做的是像这样使用 foreach 单独分配每个值

foreach($jobModel as $job){
    $job->assignInAccount($account_id);
}

但是,这显然很慢,因为如果我在 $jobModel 中有大量记录,并且每个记录都在 assignInAccount() 中进行数据库查询,如果数据库很慢,这显然需要一些时间。

我在寻找什么

我想知道是否有更有效的方法来执行此操作,以便我可以一次将inAccount 分配给所有工作记录。我考虑过使用afterFind(),但我认为这行不通,因为我需要指定一个特定的参数。我想知道是否有一种方法可以传入整个模型(或者至少是模型/模型属性数组,然后只运行一个查询来执行所有分配。

我应该提到我确实需要以原始的$jobModel activerecord 结束

【问题讨论】:

  • 您能解释一下为什么要添加此标志吗??
  • 我正在使用一个 yii 小部件,它创建一个给定 activerecord 和 flag 属性(在这种情况下为inAccount)的对偶列表,并且 flag 属性将确定在对偶列表的哪一侧放置型号
  • 您可以使用选择连接来获取与查询匹配或不匹配的值..
  • 谢谢!现在似乎快了不少。

标签: php activerecord model yii2


【解决方案1】:

感谢 scaisEdge 的回答,我能够想出一个替代解决方案,首先找到需要像这样标记的一系列工作:

    $inAccountJobs = array_column(Yii::$app->db->createCommand('Select * from job_code_accounts where ACCOUNT_ID = :account_id')
        ->bindValues([':account_id' => $account_id])->queryAll(), 'JOB_CODE');

然后检查每个作业记录,看看它是否像这样出现在这个数组中

    foreach($jobModel as $job){
        if(in_array($job->JOB_CODE, $inAccountJobs))
            $job->inAccount = -1;
        else
            $job->inAccount = 0;
    }

似乎明显更快,因为它只需要一个查询。

【讨论】:

  • 直接命令的使用总是比 activeRecord (ORM) 快.. 但是您可以使用左连接与匹配的 matchinh 表来改进查询,您可以在不能分配的地方分配一个值仅在一个查询中分配另一个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
相关资源
最近更新 更多