Yii2中能否通过多层hasMany关联获取唯一Acquisitor对象?
问题描述
现有如下模型关联关系:
- Order模型关联多个Product模型,关联方法定义:
public function getProducts() { return $this->hasMany(Product::class, ['id' => 'id_product']); }
- Product模型关联多个Acquisitor模型,关联方法定义:
public function getAcquisitors() { return $this->hasMany(Acquisitor::class, ['id' => 'id_acquisitor']); }
现在有两个疑问:
- 能否在Order模型中编写关联方法,返回包含唯一Acquisitor实例的ActiveQuery?
- 若在Order中编写如下关联方法,是否会返回重复的Acquisitor实例?能否实现去重?
public function getAcquisitors() { return $this->hasMany(Acquisitor::class, ['id' => 'id_acquisitor'])->via('products'); }
解答
- 直接使用
->via('products')的这个关联方法会返回重复的Acquisitor实例。原因很简单:如果同一个Acquisitor关联了多个Product,且这些Product都属于同一个Order,关联查询时会因为多表关联的逻辑,把同一个Acquisitor重复返回多次。 - 当然可以实现去重,有两种常用方案:
- 调用
distinct()方法:在关联链中添加distinct(),让SQL自动过滤重复记录。修改后的代码如下:
这个操作会在生成的SQL语句中加入public function getAcquisitors() { return $this->hasMany(Acquisitor::class, ['id' => 'id_acquisitor']) ->via('products') ->distinct(); }DISTINCT关键字,直接去掉重复的Acquisitor记录。 - 使用
groupBy()分组:根据Acquisitor的主键字段进行分组,也能达到去重效果。假设Acquisitor表的主键是id,代码可以写成:
注意要替换成你实际项目中Acquisitor表的主键字段名,避免出错。public function getAcquisitors() { return $this->hasMany(Acquisitor::class, ['id' => 'id_acquisitor']) ->via('products') ->groupBy('acquisitor.id'); }
- 调用
内容的提问来源于stack exchange,提问作者rosecabbagedragon
相关产品推荐
相关产品推荐

