首页 > 解决方案 > 如何在具有关系 SUM 的 Laravel 模型上使用预先加载 - 当前正在获取多个查询 (N+1)

问题描述

在我的模型中,我附加了一个关系的 SUM 计算,该关系导致为 projectHours 属性运行 80 个查询。

如果我不附加 projectHours,我会收到 6 个查询。

我相信这是关系模型中的 N+1 问题。

有没有办法在模型中使用预先加载来减少我的查询?

还是我应该以不同的方式解决这个问题?有人建议我将其重构为 Resource 并将即时加载查询包装在一个范围内,以便您可以在控制器中执行此操作,但我认为资源更多用于 API 端点。

感谢帮助。


class Project extends Model
{

    protected $appends = ['projectHours'];


    public function jobs()
    {
        return $this->hasMany('App\JobItem', 'project_id', 'id');
    }

    public function getProjectHoursAttribute()
    {
        return $this->jobs()->sum('hours');
    }

}

标签: laraveleloquent

解决方案


所以你的 (N + 1) 来自这里:

$this->jobs()->sum('hours');

它是由您jobs作为查询构建器实例的关系访问引起的jobs()

如果你想预加载关系然后对结果求和,你可以这样做:

$this->jobs->sum('hours');

然后使用 Eloquent Collectionsum方法


例子

$project = Project::with('jobs')->find(1);

$hours = $project->projectHours;

推荐阅读