【问题标题】:Cdbcriteria->With, Many To Many Relation And Method Findall(). Strange BehaviorCdbcriteria-> 使用多对多关系和方法 Findall()。奇怪的行为
【发布时间】:2014-02-25 14:53:42
【问题描述】:

社区!

我需要使用多对多关系进行大型关系查询。我在使用模型的 $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 中有一个表,当我使用延迟加载时,一切正常。

现在,我正在尝试使用 with 进行关系查询:

$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 条记录的数组呢?请解释一下,伙计们!

附言我已经使用 $criteria->join 而不是 with 解决了这个问题,findall 将它应该返回的 8 条记录返回给我,但我想在我的项目中使用...

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

【问题讨论】:

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


    【解决方案1】:

    在结果中您似乎只有 4 次操作的记录。每个操作有 2 个角色。因此,对于类似 ORM 的解决方案,这是正确的行为。 Operations::model()-&gt;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>';
    }
    

    【讨论】:

    • 感谢您的回答,但我需要急切地加载。要通过 1 个查询获得我需要的结果。我有你提供的解决方案,但我选择重构它,因为有几个不需要的查询而不是 1 个关系查询。
    • 如果您指定 with 和 together 标准的选项,急切加载必须正常工作。
    • 我从一开始就指定了和一起。请看我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2018-07-20
    相关资源
    最近更新 更多