Activerecord 如何使用Yii中的dataprovider获取联接表的所有列?

Activerecord 如何使用Yii中的dataprovider获取联接表的所有列?,activerecord,orm,yii,Activerecord,Orm,Yii,我的控制器 $criteria = new CDbCriteria(); $criteria -> select = 't.*,b.*'; $criteria -> join = 'INNER JOIN tbl_b b on b.b_id = t.id '; $criteria -> join .= 'INNER JOIN tbl_c c on c.id = b.c_id'; $criteria -> condition = 'c.id = :cid'; $criteri

我的控制器

$criteria = new CDbCriteria();
$criteria -> select = 't.*,b.*';
$criteria -> join = 'INNER JOIN tbl_b b on b.b_id = t.id ';
$criteria -> join .= 'INNER JOIN tbl_c c on c.id = b.c_id';
$criteria -> condition = 'c.id = :cid';
$criteria -> params = array(':cid' => 1);
$dataProvider = new CActiveDataProvider('tbl_a',array(
            'criteria' => $criteria
        ));
$this->render('view',array('dataProvider' => $dataProvider));
我的看法

$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'my-grid',
'dataProvider' => $dataProvider,
'columns' => array(
    'name',
    'description',
    array(
        'header' => 'Column from tbl_b',
        'value' => ''
    ),      
        array(
        'class'=>'CButtonColumn',
        'template' => '{view}'
), ),));
我的问题是:如何显示
tbl\u b
中列的值。由于在
dataprovider
中,我指定了
tbl_a
,它仅从
tbl_a
中提取数据,而不是
tbl_b
,尽管我也从
tbl_b
中选择了所有记录

据我所知,它应该显示为
$data->tbl\u b->col\u b
。但这会给出错误,因为未定义tbl_a。tbl_b我想知道是什么问题?

是否与关系有关?
tbl\u a
tbl\u c
通过
tbl\u b
相互关联。i、 e
tbl_b
有两列链接
tbl_a
tbl_c
的主id

注:名称和说明来自tbl_a,并显示出来


请建议

对于这类事情,我通常会在ActiveRecord中创建一个属性

class A extends CActiveRecord {

    public $bAttribute1

}
当我将表
A
与表
B
连接时,我重命名了
B
中的字段,我想用我创建的属性显示该字段(在本例中为
batAttribute

然后我可以在GridView中显示
bAttribute1

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider' => $dataProvider,
    'columns' => array(
        'bAttribute1',  
)));
这应该是有效的。但缺点是,如果要显示联接表中的许多列,则必须创建许多属性

更新

奇怪,所以我试着从头做起。我创建了两个表
ModelA
ModelB
,如下所示

CREATE TABLE IF NOT EXISTS `ModelA` (
  `id` int(11) NOT NULL,
  `attribute2` int(11) NOT NULL,
  `attribute3` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `ModelB` (
  `id` int(11) NOT NULL,
  `aId` int(11) NOT NULL,
  `attribute3` int(11) NOT NULL,
  `attribute4` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
如您所见,
ModelB
中的
aId
ModelA
的外键。然后我举了一些例子

INSERT INTO `ModelA` (`id`, `attribute2`, `attribute3`) VALUES
(1, 1, 1),
(2, 2, 2);
INSERT INTO `ModelB` (`id`, `aId`, `attribute3`, `attribute4`) VALUES
(1, 1, 10, 100),
(2, 2, 20, 200),
(3, 1, 30, 300),
(4, 1, 40, 400);
因此,
ModelA
中的条目#1将被
ModelB
中的3个条目引用,而条目#2将只有1个条目

然后我创建了模型代码

class ModelA extends CActiveRecord {
    public $bAttribute3;
    public $bAttribute4;
    public static function model($className = __CLASS__) {
            return parent::model($className);
    }
}
请参见模型中的
bAttribute3
bAttribute4
,我将
attribute3
attribute4
分别放在
ModelB
表中。然后在控制器中,我创建了数据提供者

public function actionIndex(){
    $dataProvider = new CActiveDataProvider('ModelA', array(
        'criteria' => array(
            'select' => array(
                '`t`.*', 
                '`b`.`attribute3` AS `bAttribute3`',
                '`b`.`attribute4` AS `bAttribute4`'
            ),
            'join' => 'JOIN `ModelB` AS `b` ON `b`.`aId` = `t`.`id`',
        )
    ));
    $this->render('index', array(
        'dataProvider' => $dataProvider,
    ));
}
在我看来,我做到了这一点

$this->widget('zii.widgets.grid.CGridView', array(
    'id' => 'my-grid',
    'dataProvider' => $dataProvider,
    'columns' => array(
        'id',
        'attribute2',
        'attribute3',
        'bAttribute3',
        'bAttribute4',
    ),
));
这就是我看到的


这是你想要的吗?即使对于CActiveDataProvider,我通常也是这样做的。我想您可能会在代码中遗漏一些内容。

我尝试了这个。。。。我认为这应该行得通,但没有。数据提供程序不包含本地创建的变量的值。它只有tblA的记录,没有bAttribute1。有什么问题吗?是我又错过了什么,还是解决方案不起作用?当我尝试查询时,它工作正常!只是在使用数据提供程序时没有。我更新了我的答案。我试着从零开始做一个,效果很好。哇!!这是一个很好的回答!但正如我在问题中提到的那样,我的情况没有什么不同。表A和表c没有直接连接,因此它们没有外部关系。它们通过表B连接在一起。TableB包含tableA和tableC的主键,并将它们关联起来。我知道这听起来有点奇怪,但我必须以这种方式维持外交关系。那么,对于这种情况,解决方案是什么?如果它们有直接关系,那么您的代码是正确的,但在我的情况下,它不是。那么,对这个场景有什么建议吗?事实上,几乎是一样的,你只需要添加另一个属性,比如说
cAttribute1
,在选择中你只需将字段
c.attribute1重命名为cAttribute1
,你有没有尝试过这样的列
'value'=>'$data->tableC->attribute1
$this->widget('zii.widgets.grid.CGridView', array(
    'id' => 'my-grid',
    'dataProvider' => $dataProvider,
    'columns' => array(
        'id',
        'attribute2',
        'attribute3',
        'bAttribute3',
        'bAttribute4',
    ),
));