【问题标题】:Laravel Eloquent Repository - Query giving unexpected result?Laravel Eloquent Repository - 查询给出意外结果?
【发布时间】:2019-12-06 12:37:38
【问题描述】:

我正在使用 laravel 雄辩的查询来获取属于一个部门的所有学生的结果。 关系是这样的: 每个部门都有课程。 每个班级都有学生。

如果我们在 MySQL 上编写,我们可以有两个版本: 假设我们想要属于第 5 系的学生。

1.

select * from class
   inner join student on class.id = student.class_id
   where class.department_id = 5;

等效的 Laravel Eloquent 查询:

return $classRepo->where(['department_id'=>5])
            ->select(['id','department_id'])
            ->with(['students'])
            ->get();

2.

select * from student
   inner join class on class.id = student.class_id
   where class.department_id = 5;

等效的 Laravel Eloquent 查询:

return $studentRepo
        ->with(['class' => function($query){
            $query->select(['id', 'department_id'])
                ->where(['department_id' => 5]);
        }])
        ->get();

没想到第一个版本的结果是这样的:

[
    {
        "id": 3,
        "department_id" : 5,
        "students": [
            {
                "id": 61060,
                "name" : "Mark"
            },
            {
                "id": 61061,
                "name" : "Tony"
            }
           ]
    }
]

第二个版本是这样的:

[
    {
        "id": 61057,
        "name" : "Smith",
        "class": null
    },
    {
        "id": 61058,
        "name" : "Jason",
        "class": null
    },
    {
        "id": 61060,
        "name" : "Mark",
        "class": {
            "id": 3,
            "department_id": 5
        }
    },
    {
        "id": 61061,
        "name" : "Tony",
        "class": {
            "id": 3,
            "department_id": 5
        }
    }
]

谁能解释一下这两个版本的结果有何不同? 为什么我在第二个版本中针对类键有空值? laravel eloquent 到底是如何处理查询的?

classRepo 是“类”类的对象

class Classes extends Model{

    public function students()
    {
        return $this->hasMany('App\repoModels\Student','class_id','id');
    }

}

studentRepo 是 'Student' 类的对象

class Student extends Model{

   public function class()
    {
        return $this->hasOne('App\repoModels\Classes', 'id', 'class_id');
    }

}

【问题讨论】:

  • 嗨,我猜这两个带有“null”的结果没有关系,您是否希望它们不会出现在查询中?
  • 是的,我希望那些不应该来。

标签: php laravel-5 eloquent repository-pattern


【解决方案1】:

您的查询未正确约束。

你雄辩的询问

return $studentRepo
        ->with(['class' => function($query){
            $query->select(['id', 'department_id'])
                ->where(['department_id' => 5]);
        }])
        ->get();

是说“返回所有学生和他们相应的班级,但如果班级在部门 5,则只给我班级”。

你想说的是“返回所有学生及其相应的班级,但只给我学生如果他们在部门 5 的班级”。

这里的解决方法是:

return $studentRepo
        ->with(['class' => function($query){
            $query->select(['id', 'department_id'])
                ->where(['department_id' => 5]);
        }])->whereHas('class', function($query) {
            $query->where('department_id', 5);
        })->get();

请参见“查询关系存在”下的:https://laravel.com/docs/5.8/eloquent-relationships

【讨论】:

    【解决方案2】:

    这看起来是左连接,而不是内连接。

    如果你从学生开始,eloquent 会显示所有学生和他们对应的班级,即使它是空的。

    如果从班级开始,eloquent 会显示所有班级及其对应的学生(忽略没有班级的学生)。

    如果您希望两个查询返回相同的结果,您可能必须专门要求 eloquent 进行内部连接。

    【讨论】:

    • 是的,我也是这么想的,但是使用 with 不会进行内部连接吗?
    猜你喜欢
    • 2019-03-06
    • 1970-01-01
    • 2023-03-05
    • 2020-09-24
    • 2018-10-22
    • 2021-10-26
    • 2019-12-24
    • 2021-05-28
    • 2018-11-04
    相关资源
    最近更新 更多