Laravel: 构建不同条件的基础查询

问题描述 投票:0回答:1

在我的应用程序中,有一种情况是,我必须运行同一个查询3次,但每次查询都有一些不同的条件。例如,在我的应用程序中,有这样的情况:我必须运行3次相同的查询,但每次查询都有一些不同的条件。active: 查询+ active conditions, inactive: 查询+ inactive conditions.等等。

这是我的代码。

$activeInventory = $inactiveInventory = \DB::table('device_inventories')
  ->where([
    'device_companies.company_id'  => session()->get('COMPANY_ID'),
    'device_inventories.device_id' => $Self->id,
  ])->select([
    ...
  ])
  ->join('devices', 'devices.id', '=', 'device_inventories.device_id')
  ->join('device_companies', 'device_companies.id', '=', 'devices.device_company_id');

// active records
$active = $activeInventory
  ->where('device_inventories.status', 'T')
  ->join('u_devices', 'u_devices.device_inventory_id', '!=', 'device_inventories.id')
  ->get() ?? null;

// inactive records
$inactive = $inactiveInventory
  ->where('device_inventories.status', 'F')
  ->get() ?? null;

// returning data
return [
  'model' => $Self,
  'active' => $active,
  'inactive' => $inactive,
];

注意,我已经加入了 u_devices 表中 Active 查询。但当我运行 Inactive 查询,加入 u_devices 也存在于该查询中。即使我使用不同的变量来存储基础查询和运行它。

我在这里做错了什么?

php sql laravel query-builder base
1个回答
3
投票

这是由于追加查询逻辑的工作方式造成的。当你对一个版本的查询进行追加修改时,它会修改原来的查询,所以任何后续的基础查询也会受到影响。你应该可以通过以下方法来解决这个问题 clone 在PHP中使用关键字。

$baseQuery = \DB::table('device_inventories')->where([
  'device_companies.company_id'  => session()->get('COMPANY_ID'),
  'device_inventories.device_id' => $Self->id,
])->select([
  ...
])
->join('devices', 'devices.id', '=', 'device_inventories.device_id')
->join('device_companies', 'device_companies.id', '=', 'devices.device_company_id');

$active = (clone $baseQuery)->where('device_inventories.status', 'T')
->join('u_devices', 'u_devices.device_inventory_id', '!=', 'device_inventories.id')
->get() ?? null;

$inactive = (clone $baseQuery)->where('device_inventories.status', 'F')->get() ?? null;

return [
  'model' => $Self,
  'active' => $active,
  'inactive' => $inactive,
];

当你使用 clone你在你的代码中创建了一个查询的副本,因为它是在你的代码中的那个点,所以后续的使用不会 "污染 "查询。


2
投票

你需要得到一个新的构建器对象的实例。$activeInventory 是持有你告诉它的所有条件,其中包括所有的 where 条件。你会想要一个构建器的副本,对它进行不同的查询。

$something = (clone $activeInventory)->...;
$else = (clone $activeInventory)->...;
© www.soinside.com 2019 - 2024. All rights reserved.