Yii2使用左连接将SqlDataProvider转换为ActiveDataProvider

时间:2016-03-14 06:52:49

标签: mysql yii2 left-join

我有两张桌子:电话,电话

两种型号:通话,电话

和以下代码:

$q = 'select 
      c.calling, sp.name as srcname, sp.org as srcorg, 
      c.called, dp.name as dstname, dp.org as dstorg 
      from Calls c 
      left join Phones sp on c.calling = sp.num 
      left join Phones dp on c.called = dp.num ORDER BY c.time '
$sql = Yii:$app->db->createCommand($q)
$count = $sql->queryScalar();
$dataProvider = new SqlDataProvider([
   'sql' => $q,
   'pagination' => [
      'pageSize' => 25,
    ],
   'totalCount' => $count,
]);

如何将其转换为ActiveDataProvider查询?

$dataProvder = new ActiveDataProvider([
'query' => Call::find()->...,
'pagination' => [
      'pageSize' => 25,
    ],
]);

1 个答案:

答案 0 :(得分:1)

我有一些输入,你也会回答你的问题。

模型而不是原始查询

使用Gii为两个表创建模型。内置扩展,您可以在调试模式下通过调用http://yourproject.com/gii来打开它。

创建模型时,它还会建立与其他表的关系。您可以根据Yii2的model-documentationActiveRecord-documentation轻松自定义这些内容。后面还将向您展示如何指定关系here

在您的情况下,Call - 模型将有两个hasOne - 关系:

  • sourcePhone参考发起呼叫的电话型号
  • destinationPhone引用接收电话的型号

数据提供者和列出呼叫的网格视图

现在很容易启动。假设您要列出所有呼叫,您可以按如下方式进行:

<?= GridView::widget([
    'dataProvider'=>new ActiveDataProvider(['query'=>Call::find()]),
    'columns'=>[
        'id',
        [
            'label'=>Yii::t('app', 'Source phone'),
            'value'=>function ($model, $key, $index, $column) {
                return $model->sourcePhone->name;
            },
        ],
        [
            'label'=>Yii::t('app', 'Destination phone'),
            'value'=>function ($model, $key, $index, $column) {
                return $model->destinationPhone->name;
            },
        ],
        //more columns as of your requirements...
    ],
]) ?>

您现在不仅使用ActiveDataProvider,还使用Yii2的常用方式显示此类数据(关系等)。可以使用与上述相同的方式在数据提供者上自定义分页和内容。

如何在ActiveQuery

中使用join - 部分

这个很容易。一旦调用关系(延迟加载),表的实际连接将自动发生。在上面的例子中,这将发生在这里:

return $model->destinationPhone->name

这导致另一个查询填充与相应的Phone-instance的关系。如果您希望这与实际的调用查询一起发生,只需将您提供的查询扩展到ActiveDataProvdier:

'dataProvider'=>new ActiveDataProvider([
    'query'=>Call::find()->joinWith(['sourcePhone', 'destinationPhone']),
]),

joinWith - 方法告诉查询获取调用对象以及您在参数中指定的两个关系。请务必阅读documentation of this method。我还写了answer to a problem I had myself,进一步解释了它。

如果要访问相关对象的列,只需访问相关对象,如call-object的属性,然后访问属性本身。在上面的示例中,您可以看到我如何访问相关手机型号的name - 属性。

告诉我您是否需要有关某些部件的更多信息。

相关问题