在yii2中,“andFilterWhere”与“joinWith()”一起使用是正确的,但与“with()”一起使用是不正确的

9jyewag0  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(246)

我在yii2工作。
employeecompany表的雇员包含company_id
如果我使用joinWith(),则过滤器搜索运行正常

$query = Employee::find();
  $query->joinWith(['company']);

    $dataProvider = new ActiveDataProvider([
        'query'         => $query, 
        'pagination'    => false, 
        'sort'          => false,
    ]);

    if (!($this->load($params) && $this->validate())) {
        return $dataProvider;
    }

  //and below is the filterwhere
 $query->andFilterWhere(['like', 'company.name', $this->company_id]);

但在使用with()进行查询时出现问题

$query = Employee::find()->with(['company']);

    $dataProvider = new ActiveDataProvider([
        'query'         => $query, 
        'pagination'    => false, 
        'sort'          => false,
    ]);

    if (!($this->load($params) && $this->validate())) {
        return $dataProvider;
    }

//when query contain with() then this filter is not working.
$query->andFilterWhere(['like', 'company.name', $this->company_id]);

当我使用with()时,会产生错误

Database Exception – yii\db\Exception
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'company.name' in 'where clause'
The SQL being executed was: SELECT COUNT(*) FROM `employee` WHERE `company`.`name` LIKE '%1%'

员工与公司的关系如下:

public function getCompany(){
    return $this->hasOne(Company::className(),  ['id'=> 'company_id']);
}

有人能帮助我或指导我如何在查询中使用with()正确过滤数据吗?谢谢。

bnlyeluc

bnlyeluc1#

当需要根据相关表中的列进行筛选时,不能交换joinWith()with()方法,因为这两个方法执行的是完全不同的操作。
joinWith()join()这样的方法实际上修改了查询,将“JOIN”部分添加到SQL查询中。joinWith中的with允许您通过模型中的关系定义来指定连接表。joinWith中的提前加载只是副作用,您甚至可以通过将false作为第二个参数传递来关闭它。
当您执行以下操作时:

Employee::find()->joinWith(['company'])->all();

运行的查询如下所示:

SELECT * FROM employee LEFT JOIN company ON (...)

另一方面,方法with()并不修改查询本身,它只强制相关模型的提前加载,实际上第二个查询是用于预加载相关记录的,当你这样做时:

Employee::find()->with(['company'])->all();

它实际上运行如下查询:

SELECT * FROM employee;

SELECT * FROM company WHERE id IN (...company ids selected in first query...);

所以当你试着去做:

$query = Employee::find()
    ->with(['company'])
    ->andFilterWhere(['like', 'company.name', $this->company_id])
    ->all();

生成的查询为

SELECT * FROM employee WHERE company.name LIKE ...

相关问题