Yii2 使用左连接将 SqlDataProvider 转换为 ActiveDataProvider
Yii2 convert SqlDataProvider to ActiveDataProvider with left join
我有两个表:调用,Phones
两个模型:调用,Phone
和以下代码:
$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,
],
]);
我有一些意见可以回答你的问题。
模型而不是原始查询
使用 Gii 为您的两个 table 创建模型。该扩展是内置的,您可以在调试模式下通过调用 http://yourproject.com/gii
来简单地打开它。
当您创建模型时,它也会建立您与其他人的关系 table。您可以根据 model-documentation and ActiveRecord-documentation of Yii2. The later will also show you how to specify relations here.
轻松自定义这些
在您的情况下,Call
-模型将有两个 hasOne
-关系:
sourcePhone
引用发起调用phone的机型
destinationPhone
参考接收机型phone
用于列出调用的数据提供者和网格视图
启动现在很容易了。比方说你想列出所有的电话,你可以这样做:
<?= 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常用的方式来展示这样的数据(关系等)。可以像上面一样在数据提供程序上自定义分页和内容。
如何将 join
部分与 ActiveQuery
一起使用
这个很简单。 table 的实际加入将在您调用关系(延迟加载)时自动发生。在上面的示例中,这将发生在此处:
return $model->destinationPhone->name
这导致另一个查询填充与相应 Phone-实例的关系。如果您希望这与实际的调用查询一起发生,只需扩展您提供给 ActiveDataProvdier 的查询:
'dataProvider'=>new ActiveDataProvider([
'query'=>Call::find()->joinWith(['sourcePhone', 'destinationPhone']),
]),
joinWith
方法告诉查询获取调用对象以及您在参数中指定的两个关系。请务必阅读 documentation of this method. I also have written an answer to a problem I had myself,其中进一步解释了它。
如果您想访问相关对象的列,只需像调用对象的属性一样访问相关对象,然后再访问属性本身。在上面的示例中,您可以看到我如何访问相关 phone-模型的 name
-属性。
如果您需要有关某些部分的更多信息,请告诉我。
我有两个表:调用,Phones
两个模型:调用,Phone
和以下代码:
$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,
],
]);
我有一些意见可以回答你的问题。
模型而不是原始查询
使用 Gii 为您的两个 table 创建模型。该扩展是内置的,您可以在调试模式下通过调用 http://yourproject.com/gii
来简单地打开它。
当您创建模型时,它也会建立您与其他人的关系 table。您可以根据 model-documentation and ActiveRecord-documentation of Yii2. The later will also show you how to specify relations here.
轻松自定义这些在您的情况下,Call
-模型将有两个 hasOne
-关系:
sourcePhone
引用发起调用phone的机型destinationPhone
参考接收机型phone
用于列出调用的数据提供者和网格视图
启动现在很容易了。比方说你想列出所有的电话,你可以这样做:
<?= 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常用的方式来展示这样的数据(关系等)。可以像上面一样在数据提供程序上自定义分页和内容。
如何将 join
部分与 ActiveQuery
一起使用
这个很简单。 table 的实际加入将在您调用关系(延迟加载)时自动发生。在上面的示例中,这将发生在此处:
return $model->destinationPhone->name
这导致另一个查询填充与相应 Phone-实例的关系。如果您希望这与实际的调用查询一起发生,只需扩展您提供给 ActiveDataProvdier 的查询:
'dataProvider'=>new ActiveDataProvider([
'query'=>Call::find()->joinWith(['sourcePhone', 'destinationPhone']),
]),
joinWith
方法告诉查询获取调用对象以及您在参数中指定的两个关系。请务必阅读 documentation of this method. I also have written an answer to a problem I had myself,其中进一步解释了它。
如果您想访问相关对象的列,只需像调用对象的属性一样访问相关对象,然后再访问属性本身。在上面的示例中,您可以看到我如何访问相关 phone-模型的 name
-属性。
如果您需要有关某些部分的更多信息,请告诉我。