在一个查询中获取Yii2模型关系



我有模型材料与表数据有一对一的关系

当我呼叫

$material = appmodelsMaterial::find()->where(['material.id'=> 417974])->with('data')->one(); 
$material->data->title它提供查询。

尝试使用joinWith

$material = appmodelsMaterial::find()->select('"material".*,  "data".*')->where(['material.id'=> 417974])->joinWith('data')->one(); 

和在SQL查询中,我从2个表中获得所有列,但$material->data->title仍然添加额外的查询

你不能强迫Yii在同一个查询中加载模型和它的相关模型。即使您的关系是一对一的,Yii也会在单独的查询中加载相关模型。

$material = appmodelsMaterial::find()
->where(['material.id'=> 417974])
->with('data')
->one(); 

像这样使用急切加载,将导致Yii在one()方法调用期间加载相关模型,但它仍将使用单独的查询来加载相关模型的数据。

如果你想在单个查询中加载所有数据,你需要将它们作为数组加载,而不是将它们加载到model中:

$material = appmodelsMaterial::find()
->select('material.*,  data.*')
->where(['material.id'=> 417974])
->joinWith('data')
->asArray()
->one(); 

如果你真的坚持在单个查询中加载数据并将其作为模型,你可以自己实例化/填充模型及其关系。

$row = appmodelsMaterial::find()
->select('material.*,  data.*')
->where(['material.id'=> 417974])
->joinWith('data')
->asArray()
->one(); 
// Create instance of Material model
$material = appmodelsMaterial::instantiate($row);
// Populate Material model instance with loaded data
appmodelsMaterial::populateRecord($material, $row);
// Assuming the related model class is appmodelsData
// Create instance of related Data model
$data = appmodelsData::instantiate($row); 
// Populate Data model instance with loaded data
appmodelsData::populateRecord($data, $row);
// Populate data relation in Material model instance
$material->populateRelation('data', $data);

但老实说,在大多数情况下,最好让框架完成它的工作。除非加载相关模型的查询非常慢,否则删除单个查询所带来的性能改进将是最小的,并且您的代码将因加载逻辑而变得混乱。

最新更新