在Yii2的Active Record上遇到麻烦。
我想设置一个包含左连接的hasMany关系,但是这样做时,记录只填充一个关系对象。
这是当前的代码 - 将执行的查询从Yii调试复制到navicat肯定会返回多个结果。
public function getx()
{
return $this->hasMany(x::className(),['x' => 'x'])
->viaTable('a', ['arId' => 'arId'], function ($query){
$query->leftJoin('a b', 'a.type = b.type AND a.val < b.val')
->andWhere('a.foo IN (0,1,2,3)')
->andWhere('a.bar IN ((0,1,2,3)')
->andWhere('a.moo IN ((0,1,2,3)')
->andWhere('b.val IS NULL');
}
);
}
以下代码可以正常工作(当然查询不同)。
return $this->hasMany(x::className(),['x' => 'x'])
->viaTable('a', ['arId' => 'arId'], function ($query){
$query->andWhere(['and', ['foo' => [0,1,2,3]],
['bar' => [0,1,2,3]],
['moo' => [0,1,2,3]],
]
);
}
);
它在控制器中被调用,具有以下内容:
$rs = ar::find(1)->with('x')->all();
问题显然是加入 - 任何人都可以告诉我为什么会这样吗?
答案 0 :(得分:0)
请尝试一下,因为这对我有用
public function getx()
{
return $this->hasMany(x::className(), ['xId' => 'xId'])
->leftJoin('a b', 'a.type = b.type AND a.val < b.val',
function($query){
'..here you can add more join'
})
->andWhere('a.foo IN (0,1,2,3)')
->andWhere('a.bar IN ((0,1,2,3)')
->andWhere('a.moo IN ((0,1,2,3)')
->andWhere('b.val IS NULL');
}
请告诉我这是否有问题,因为我再次说它对我有用。
答案 1 :(得分:-1)
所以这就是答案!
如果有连接,则需要另外指定indexBy()以下代码:
db\ActiveQuery ln 224
if (!empty($this->join) && $this->indexBy === null) {
$models = $this->removeDuplicatedModels($models);
}
会将您转到removeDuplicatedModels()
功能。
此函数检查modelclass
参数中的主键,然后删除所有重复项。然而,联结表期待多个原色(来自父Active Record),因为它是hasMany()
关系。因此,您需要通过将indexBy
参数设置为所需的主键来覆盖此检查。
以下代码适用:
public function getx()
{
return $this->hasMany(x::className(),['xId' => 'xId'])
->viaTable('a', ['arId' => 'arId'], function ($query){
$query->leftJoin('a b', 'a.type = b.type AND a.val < b.val')
->andWhere('a.foo IN (0,1,2,3)')
->andWhere('a.bar IN ((0,1,2,3)')
->andWhere('a.moo IN ((0,1,2,3)')
->andWhere('b.val IS NULL')
->indexBy('xId')
}
);
}