2015-10-26 71 views
1

Yii2的活動記錄有些問題。Yii 2活動記錄hasMany with LeftJoin

我想設置一個包含左連接的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

你可以使用調試器和創建斷點看到'SQL'命令'leftJoin'創造??? –

+0

是的,在yii調試器中,它顯示完整的查詢並將其粘貼到navicat中,給出了所需的結果,即。正在返回多行。 – Zac

+0

說實話,我不知道'leftjoin'是如何工作的,因爲你傳遞了2個表名a和b而沒有任何分隔符或任何東西。給我一些時間,讓我試試我的項目演示,並會回覆給你。 –

回答

-1

所以這裏是答案!

如果有一個連接,你需要指定一個indexBy()其他明智下面的代碼:

db\ActiveQuery ln 224

if (!empty($this->join) && $this->indexBy === null) { 
     $models = $this->removeDuplicatedModels($models); 
    } 

會送你到removeDuplicatedModels()功能。

該函數檢查modelclass參數中的主鍵,然後刪除所有重複項。然而,聯結表期望多個初選(來自父活動記錄),因爲它是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') 
     } 
     ); 

}