Activerecord 如何使用hasOne和onCondition创建关系查询?

Activerecord 如何使用hasOne和onCondition创建关系查询?,activerecord,yii2,entity-relationship,yii2-model,Activerecord,Yii2,Entity Relationship,Yii2 Model,因为我有一个索引(user\u id,lesson\u id),所以我想用该索引进行查询 对于图像,它不使用索引,对吗 注意:用户ID它是一个整数值,而不是一个字段 //the following SQL it is my expecting: //not generate by php code. just show a example for what to do. LEFT JOIN `user_lesson_order` ON ( //user_id is current log

因为我有一个索引(
user\u id,lesson\u id
),所以我想用该索引进行查询

对于图像,它不使用索引,对吗

注意:用户ID它是一个整数值,而不是一个字段

//the following SQL it is my expecting:
//not generate by php code. just show a example for what to do.
LEFT JOIN `user_lesson_order` ON (
    //user_id is current logined 
    `user_lesson_order` . `user_id` = 29
) 
AND ( 
    `lesson_favorite` . `lesson_id` = `user_lesson_order` . `lesson_id`
)
AND ...
AND ...

//the wrong php code. it will generate a wrong sql;
public function getLessonOrder() {
    return $this->hasOne(UserLessonOrder::class, [
        UserLessonOrder::tableName() . '.user_id' => $this->user_id,
        'lesson_id' => 'lesson_id'
    ])->onCondition([
        UserLessonOrder::tableName() . '.payment_status' =>SystemCode::COMMON_PAYMENT_STATUS_YES,
        UserLessonOrder::tableName() . '.status' => SystemCode::COMMON_STATUS_ENABLE
    ]);
}
//the wrong sql:
LEFT JOIN `user_lesson_order` ON (
   //user_lesson_order.user_id = 41, this is my expect sql. 
   `lesson_favorite`.`41` = `user_lesson_order`.`user_id`

    AND `lesson_favorite`.`lesson_id` = `user_lesson_order`.`lesson_id`
) AND (
(
    `user_lesson_order`.`payment_status` = 'COMMON_PAYMENT_STATUS_YES'
) AND (
    `user_lesson_order`.`status` = 'COMMON_STATUS_ENABLE'
)
)
Unknown column 'lesson_favorite.41' in 'on clause'
fllow php代码将生成正确的sql。但它不能使用
唯一密钥(用户id,课程id)

请告诉我:

1,哪种情况将使用数据库的索引
唯一密钥(用户id,课程id)

2、如何创建这样的查询?第一个上的用户id,然后是课程id

//user_id is current logined
left join user_lesson_order on user_lesson_order.user_id = 29 
and lesson_favorite.lesson_id = user_lesson_order.lesson_id

可以使用多个字段定义关系链接

$this->hasOne(
        UserLessonOrder::class, 
        ['lesson_id' => 'lesson', 'user_id' => 'user_id']
    )
    ->onCondition([
        'payment_status' => ...
        'status'         => ...  
    ])
在关系定义中使用任何模型属性(
$this->user\u id
)在大多数情况下都会导致问题

public function getLessenOrder() {
    return $this->hasOne(UserLessonOrder::class, [
     // 'user_id'   => 'user_id', // is it part of the relation?
        'lesson_id' => 'lesson_id', 
    ])->onCondition([
        UserLessonOrder::tableName() . '.payment_status' => SystemCode::COMMON_PAYMENT_STATUS_YES,
        UserLessonOrder::tableName() . '.status'         => SystemCode::COMMON_PAYMENT_ENABLE, 
        UserLessonOrder::tableName() . '.user_id'        => $this->user_id,
    ])
}
这应该可以做到。创建的联接应使用索引。不是吗?您可以查看
运行时/logs/app.log
以查看生成了哪个查询


如果这样做有效,唯一的区别是在
hasOne()
session\u id
$link
参数中使用正确的字段名,而不是
session
。有了这个参数,您只需说出哪些字段(列)应该相关——这里不可能使用值。这可以在
onCondition()
您已经完成的操作中完成。

不要偷懒。不要只是链接图片。没人喜欢这样。请提出适当的问题。谢谢你的建议。我只是认为发送文本的格式不好。你可以格式化代码。试试看。假设回答用户必须自己编写代码,而不是只将您提供的代码复制到答案并编辑它。如果你不提出适当的问题,你将得不到多少帮助和名声。尽可能容易地写出答案。另外,如果你的问题很难理解,对其他人也没有多大帮助。谢谢你的回答。但请注意,user_id是一个常量(整数),而不是一个字段。因此,它不能使用['lesson\u id'=>'lesson','user\u id'=>'user\u id'].@hhniao抱歉,我第一次完全没有抓住你问题的重点。简而言之,您不能让yii关系以您想要的格式生成sql(关系链接始终是join语句中的第一个条件。除非您开始覆盖QueryBuilder),但是您的问题似乎与mysql完全相关,优化者应该在这两种情况下使用最佳(相同?)索引。考虑一下用相关的模式发布一个问题,并解释为什么会发生这样的事情,谢谢。但你的世界令我惊讶。我不能生成sql!!!真不敢相信。谢谢你的回答。此查询应使用正确的索引。但是,请注意,“用户id是一个值,而不是一个字段”,用户组件中的用户id。那么,您的代码可能有点错误。请更新答案。谢谢@hhniao更新了答案。你是说这个吗?否则我不知道你说常数是什么意思。我要更新这个问题。我已经添加了更多的详细信息。请再回答一遍。谢谢@hhniao再次更新。那么您的FK关系只是关于课程id,而不包含用户id?如果仍然不起作用:使用此代码生成哪个SQL查询?发表评论…@hhniao再次更新。
public function getLessenOrder() {
    return $this->hasOne(UserLessonOrder::class, [
     // 'user_id'   => 'user_id', // is it part of the relation?
        'lesson_id' => 'lesson_id', 
    ])->onCondition([
        UserLessonOrder::tableName() . '.payment_status' => SystemCode::COMMON_PAYMENT_STATUS_YES,
        UserLessonOrder::tableName() . '.status'         => SystemCode::COMMON_PAYMENT_ENABLE, 
        UserLessonOrder::tableName() . '.user_id'        => $this->user_id,
    ])
}