Cdbcriteria-> With,多对多关系和方法Findall()。奇怪的行为

时间:2014-02-25 14:53:43

标签: php yii many-to-many criteria findall

社区!

我需要使用多对多关系进行大型关系查询。我在使用$ criteria-> with和模型的findAll()方法时遇到了问题。请解释一下发生了什么事,因为我已经疯了。 :闪烁:

我有一个Operation模型,它使用多对多关系连接到Roles模型。这是Operations模型的relations()方法:

      public function relations()
    {
            // NOTE: you may need to adjust the relation name and the related
            // class name for the relations automatically generated below.
            return array(
                    'roles' => array(self::MANY_MANY, 'Roles', 'operations_in_roles(id_oper, id_role)', 'joinType'=>'INNER JOIN'),
            );
    }

我在db operations_in_roles中有一个表,当我使用延迟加载时,一切正常。

现在,我正在尝试使用:

进行关系查询
$criteria = new CDbCriteria();
$criteria->with = array('roles');
$criteria->together = true;            
$criteria->compare('t.id_contr', $cur_contr->id_contr);   
$criteria->select = array('roles.name_role_ru as sosalue_role');

$roles_and_actions = Operations::model()->findAll($criteria);

foreach($roles_and_actions as $key=>$one_record)
        {
            echo $key." "." ".$one_record->id_oper." ".$one_record->sosalue_role."<BR>";
        }

结果,findAll()返回的foreach给了我:

  0 38 teacher
  1 39 teacher
  2 40 teacher
  3 41 teacher

由ar生成的查询是:

    SELECT roles.value_role as sosalue_role, t.id_oper as id_oper, `t`.`id_oper` AS `t0_c0`, `roles`.`id_role` AS `t1_c0`, `roles`.`name_role_ru` AS `t1_c1`, `roles`.`name_role_ua` AS `t1_c2`, `roles`.`value_role` AS `t1_c3`, `roles`.`sort` AS `t1_c4` 
    FROM `operations` `t` 
    INNER JOIN `operations_in_roles` `roles_roles` ON (`t`.`id_oper`=`roles_roles`.`id_oper`) 
    INNER JOIN `roles` `roles` ON (`roles`.`id_role`=`roles_roles`.`id_role`) 
    WHERE (t.id_contr='12')

当我在我的mysql控制台或phpmyadmin等中执行查询时...结果是正确的。它有8个记录,而不是4个记录!

0 38 teacher
1 39 teacher
2 40 teacher
3 41 teacher
4 38 admin
5 39 admin
6 40 admin
7 41 admin

但为什么findAll()函数只返回4条记录的数组?请解释一下,伙计们!

P.S。我已经使用$ criteria-&gt; join解决了这个问题,而不是使用和findall返回它应该的8条记录,但我想在我的项目中使用...

我想找到这种奇怪行为的目的。请回答:)

1 个答案:

答案 0 :(得分:0)

似乎在结果中您只有4个操作的记录。每个操作都有2个角色。因此,对于类似ORM的解决方案来说,这是一种正确的行为。 Operations::model()->findAll返回4个操作。如果要读取角色,则需要嵌套循环:

foreach($roles_and_actions as $key=>$one_record)
{
    echo $key." "." ".$one_record->id_oper;
    foreach ($one_record->roles as $role) 
    {
        echo $role->name_role_ru;
    }
    echo '<br>';
}