如何使用急切加载来查询尽可能少的数据?
Posted
技术标签:
【中文标题】如何使用急切加载来查询尽可能少的数据?【英文标题】:How to use eager loading to query as less data as possible? 【发布时间】:2018-11-19 01:43:36 【问题描述】:我正在使用 Eloquent ORM,我想设置一个预先加载以查询尽可能少的数据。
我有三个表 countries
、states
和 cities
,我想获取某个国家/地区的所有州和城市,而不需要有关该国家/地区的其他信息。
我的模型:
国家
public function states ()
return $this->hasMany(State::class);
状态
public function country ()
return $this->belongsTo(Country::class);
public function cities ()
return $this->hasMany(City::class);
城市
public function state ()
return $this->belongsTo(State::class);
例如,获取美国的所有州和城市。我想得到如下数据。
[
id: 1,
name: 'California',
cities: [
id: 1,
name: 'Los Angeles'
]
]
我怎样才能只使用 Eloquent ORM 助手而不使用 where
或原始 SQL 来实现这一点?
【问题讨论】:
您是否已经定义了模型及其关系?您可以将它们添加到问题中吗? 我刚刚编辑过。检查一下! 您能否就答案提供反馈? @jonas-staudenmeir 我一直在等待使用 Eloquent Relations (Illuminate\Database\Eloquent\Relations
) 的答案。我不认为我得到的答案是令人满意的。也许我需要编辑我的问题...
你是什么意思?两个答案都使用 Eloquent 关系。
【参考方案1】:
你可以这样:
$data = Country::with([
'states' => function ($query)
$query->with([
'cities'
]);
])->get(['id']);
这更具可读性,不需要原始查询
【讨论】:
【参考方案2】:您可以像这样限制列:
Country::with('states:id,name,country_id', 'states.cities:id,name,state_id')->get(['id']);
您必须选择外键列,因为它们是匹配结果所必需的。
您也可以将其集成到states
关系中:
public function states ()
return $this->hasMany(State::class)->select('id', 'name', 'country_id')
->with('cities:id,name,state_id');
当您访问/加载states
时,这将自动加载cities
。
【讨论】:
指定外键是不必要的,至少在官方 Laravel 文档中是这样解释的 -> ` 使用此功能时(渴望加载特定列),您应该始终在您希望检索的列。` lara docs->laravel.com/docs/5.6/eloquent-relationships#eager-loading 这是必要的。在文档示例中,id
是外键。在这种情况下,states.id
、country_id
和 state_id
是必需的外键。
在文档示例中id
是作者表的主键而不是外键:/
文档中的这句话措辞不好,它仅指BelongsTo
关系。在这种情况下,我们有两个HasMany
关系。在没有country_id
或state_id
的情况下尝试我的答案,它不会起作用。
我扩展了我的答案。以上是关于如何使用急切加载来查询尽可能少的数据?的主要内容,如果未能解决你的问题,请参考以下文章
WCF 数据服务和 EF4 CTP5,如何为查询配置默认的急切加载模式?