Laravel 预加载似乎不起作用
Laravel eager loading does not seem to work
查看下图中的数据库关系。
我想显示教室的所有可用时间(每天 9 小时),包括该小时的容量和该小时允许的部门,包括被排除在课堂之外的科目或教室是专属的。
在我的 show.blade.php 中,我构建了一个 table 并且每个 table 单元格显示一个 availableHour。由于这需要两个循环,一个用于几天,一个用于一天中的某个小时,我想急切地将这些关系加载到教室中。但是根据完成请求所花费的时间(将近 2 秒)和 telescope 报告的查询数量来判断,无论是否预先加载,数据库都会受到质疑。
在我的控制器中,我加载了这样的关系:
$classroom->load('availableHours.allowedDepartments.exclusiveSubjects.subject',
'availableHours.allowedDepartments.excludedSubjects.subject',
'availableHours.allowedDepartments.department');
如果我倾倒教室,关系就会加载。在我的 show.blade.php 中,我像这样遍历 availableHours:
<!-- loop through all the hours of the day -->
@for($i=1;$i<=$maxHour;$i++)
<tr>
<td>
<a href="/classrooms/{{$classroom->number}}/0/{{$i}}/edit">
{{$i}}
</a></td>
<!-- loop through all the days -->
@foreach($days as $day)
<!-- show the available hour either in green (available) or red (unavailable)-->
<td>
<a href="/classrooms/{{$classroom->number}}/{{$day->id}}/{{$i}}/edit">
<!-- show the capacity of the hour of the day-->
{{ $classroom->availableHours()->where([['day_id','=',$day->id],['hour_of_day',$i]] )->first()->capacity }} <br/>
@foreach($classroom->availableHours()->where([['day_id','=',$day->id],['hour_of_day',$i]] )->first()->allowedDepartments as $allowedDepartment)
<!-- show the permitted departments along with any exclusive or excluded subjects-->
{{$allowedDepartment->department->name}}
@foreach ($allowedDepartment->exclusiveSubjects as $subjectDepartment)
{{$subjectDepartment->subject->code}}
@endforeach
<br/>
@endforeach
</a></td>
@endforeach
</tr>
@endfor
正如我所说,这会导致再次查询数据库而不是使用预加载的关系。我做错了什么?
当你调用$classroom->availableHours()
时,你实际上是在再次查询关系函数并返回它,而不是访问已经存在的关系函数。
在控制器中加载关系后,对象将填充包含所需值的属性。所以加载后,改用$classroom->availableHours
。 (就像你对 $allowedDepartment->exclusiveSubjects
所做的那样)
查看下图中的数据库关系。
我想显示教室的所有可用时间(每天 9 小时),包括该小时的容量和该小时允许的部门,包括被排除在课堂之外的科目或教室是专属的。 在我的 show.blade.php 中,我构建了一个 table 并且每个 table 单元格显示一个 availableHour。由于这需要两个循环,一个用于几天,一个用于一天中的某个小时,我想急切地将这些关系加载到教室中。但是根据完成请求所花费的时间(将近 2 秒)和 telescope 报告的查询数量来判断,无论是否预先加载,数据库都会受到质疑。
在我的控制器中,我加载了这样的关系:
$classroom->load('availableHours.allowedDepartments.exclusiveSubjects.subject',
'availableHours.allowedDepartments.excludedSubjects.subject',
'availableHours.allowedDepartments.department');
如果我倾倒教室,关系就会加载。在我的 show.blade.php 中,我像这样遍历 availableHours:
<!-- loop through all the hours of the day -->
@for($i=1;$i<=$maxHour;$i++)
<tr>
<td>
<a href="/classrooms/{{$classroom->number}}/0/{{$i}}/edit">
{{$i}}
</a></td>
<!-- loop through all the days -->
@foreach($days as $day)
<!-- show the available hour either in green (available) or red (unavailable)-->
<td>
<a href="/classrooms/{{$classroom->number}}/{{$day->id}}/{{$i}}/edit">
<!-- show the capacity of the hour of the day-->
{{ $classroom->availableHours()->where([['day_id','=',$day->id],['hour_of_day',$i]] )->first()->capacity }} <br/>
@foreach($classroom->availableHours()->where([['day_id','=',$day->id],['hour_of_day',$i]] )->first()->allowedDepartments as $allowedDepartment)
<!-- show the permitted departments along with any exclusive or excluded subjects-->
{{$allowedDepartment->department->name}}
@foreach ($allowedDepartment->exclusiveSubjects as $subjectDepartment)
{{$subjectDepartment->subject->code}}
@endforeach
<br/>
@endforeach
</a></td>
@endforeach
</tr>
@endfor
正如我所说,这会导致再次查询数据库而不是使用预加载的关系。我做错了什么?
当你调用$classroom->availableHours()
时,你实际上是在再次查询关系函数并返回它,而不是访问已经存在的关系函数。
在控制器中加载关系后,对象将填充包含所需值的属性。所以加载后,改用$classroom->availableHours
。 (就像你对 $allowedDepartment->exclusiveSubjects
所做的那样)