Я пытаюсь ->find('all')
и содержать hasMany () Расписания, которые serveTo () Службы в методе индекса контроллера служб. Сервис может фактически иметь от нуля до многих расписаний. Тестирование и опыт использования метода представления служб привели меня к мысли, что проблема связана с полем БД, в котором используется ключевое слово. Это область, в которой я не вижу необходимости в настоящее время. К сожалению, у меня нет возможности изменить структуру базы данных.
Я попытался ->contain()
и указал нужные мне поля, включая основные поля, содержащиеся в расписаниях. Результаты были такими же, как попытка № 1, перечисленная ниже. Я успешно использовал это в другой модели.
Я пытался ->selectAllExcept($tableObj, ['FieldToExclude'])->contain()
. Я также пытался выполнить beforeFind () в SchedulesTable. php после исследования здесь , но функция никогда не вызывалась.
Я могу обойти проблему в методе view указав поля в находке непосредственно в таблице служб. Тем не менее, это не жизнеспособный вариант в методе индекса. Я могу сделать все 1055 *, чтобы получить соответствующие записи, но это своевременно и побеждает фантастические преимущества Cake. Контейнер - это круто, и это именно то, что мне нужно.
Неправильно ли настроены ownTo & hasMany? Я что-то упустил в коде $ query? Я прочитал документацию и знаю, что мне не хватает того, что, вероятно, очевидно для многих. Я знаю, что дошел до разочарования, которое не позволяет мне думать ясно. ;) Я даже отошел на день, надеясь, что это поможет.
Заранее благодарю за любую помощь, которая может быть оказана. Это будет высоко оценено.
ServicesTable. php
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('OSCL');
$this->setDisplayField('DocNum');
$this->setPrimaryKey('DocNum');
$this->belongsTo('Locations', [
'className' => 'Locations',
'bindingKey' => 'Address',
'foreignKey' => 'BPShipCode',
'joinType' => 'INNER'
]
);
$this->hasMany('Schedules', [
'className' => 'Schedules',
'foreignKey' => 'SrcvCallID',
'bindingKey' => 'CallID'
]
);
}
и SchedulesTable. php
use Cake\Event\Event;
use ArrayObject;
class SchedulesTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('SCL6');
$this->setDisplayField('Technician');
$this->setPrimaryKey(['SrcvCallID', 'Line']);
$this->belongsTo('Services', [
'className' => 'Services',
'foreignKey' => 'SrcvCallID',
'bindingKey' => 'CallID'
]
);
$this->hasOne('Employees', [
'className' => 'Employees',
'foreignKey' => 'empID',
'bindingKey' => 'Technician'
]
);
}
/*
Added to class after the original 3 attempts.
Re-attempted the queries. Function made no difference.
Debug & die within the function showed that the function was never called.
*/
public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary)
{
return $query->selectAllExcept($this, ['Close']);
}
}
Попытка # 1 возвращает ожидаемое количество записей но массив расписаний пуст. Я не получаю никаких сообщений об ошибках, и журнал запросов не показывает никаких попыток доступа к таблице расписаний.
$query = $this->Services->find('all')
->where($conditions)
->order([$sort => $direction])
->contain(['Schedules']);
Отладка $ query-> toArray (); В таблице более 100 полей. Здесь я удалил многие из них для наглядности.
\src\Controller\ServicesController.php (line 124)
[
(int) 0 => object(App\Model\Entity\Service) {
'callID' => (int) 361893,
'subject' => 'Printer jam',
'customer' => 'C202044',
'custmrName' => 'Some Company',
'contctCode' => (int) 986,
'manufSN' => '',
'internalSN' => '16J151800861',
'createDate' => object(Cake\I18n\FrozenTime) {
'time' => '2020-03-17 00:00:00.000000-04:00',
'timezone' => 'America/New_York',
'fixedNowTime' => false
},
'createTime' => (int) 1612,
'closeDate' => null,
'closeTime' => null,
'DocNum' => (int) 316939,
'Series' => (int) 30,
'schedules' => [],
'[new]' => false,
'[accessible]' => [],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Services'
},
]
Журнал запросов
SELECT
Services.callID AS [Services__callID], Services.subject AS [Services__subject], Services.customer AS [Services__customer], Services.custmrName AS [Services__custmrName], ...
FROM
OSCL Services
WHERE
(
Services.status = 7
OR Services.status = -3
)
ORDER BY Services.DocNum DESC OFFSET 0 ROWS FETCH FIRST 20 ROWS ONLY
SELECT
(
COUNT(*)
) AS [count]
FROM
OSCL Services
WHERE
(
Services.status = 7
OR Services.status = -3
)
При попытке # 2 генерируется ошибка запроса SQL Ошибка: SQLSTATE [42000] : [Microsoft] [ODB C Драйвер 17 для SQL Сервер] [SQL Сервер] Неверный синтаксис рядом с ключевым словом «Закрыть» ». Имеет смысл, потому что поведение модели по умолчанию - выбрать все поля.
$query = $this->Services->find('all')
->where($conditions)
->order([$sort => $direction])
->select($this->Services->Schedules);
Попытка # 3. Я попытался передать объект таблицы -> selectAllExcept () и исключить проблемное поле. Построитель запросов неправильно строит запрос, используя поля из таблицы расписаний, как если бы они были частью таблицы служб
$query = $this->Services->find('all')
->where($conditions)
->order([$sort => $direction])
->selectAllExcept($this->Services->Schedules, ['Close'])
->contain(['Schedules']);
Запрос, построенный построителем запросов. SrcvCallID, Line & Technician - это все поля таблицы Расписаний, а не Службы.
SELECT
Services.SrcvCallID AS [Services__SrcvCallID], Services.Line AS [Services__Line], Services.Technician AS [Services__Technician], ...
FROM
OSCL Services
WHERE
(Services.status = :c0 OR Services.status = :c1)
ORDER BY
Services.DocNum DESC
OFFSET 0 ROWS FETCH FIRST 20 ROWS ONLY
Вот пример ожидаемых результатов , созданных вручную из функции представления.
[
(int) 0 => object(App\Model\Entity\Service) {
'callID' => (int) 361893,
'subject' => 'Printer jam',
'customer' => 'C202044',
'custmrName' => 'Some Company',
'contctCode' => (int) 986,
'manufSN' => '',
'internalSN' => '16J151800861',
'createDate' => object(Cake\I18n\FrozenTime) {
'time' => '2020-03-17 00:00:00.000000-04:00',
'timezone' => 'America/New_York',
'fixedNowTime' => false
},
'createTime' => (int) 1612,
'closeDate' => null,
'closeTime' => null,
'DocNum' => (int) 316939,
'Series' => (int) 30,
'schedules' => [
(int) 0 => object(App\Model\Entity\Schedule) {
'SrcvCallID' => (int) 361893,
'Line' => (int) 1,
'Technician' => (int) 243,
'StartDate' => object(Cake\I18n\FrozenTime) {
'time' => '2020-03-18 00:00:00.000000-04:00',
'timezone' => 'America/New_York',
'fixedNowTime' => false
},
'StartTime' => (int) 800,
'EndDate' => object(Cake\I18n\FrozenTime) {
'time' => '2020-03-18 00:00:00.000000-04:00',
'timezone' => 'America/New_York',
'fixedNowTime' => false
},
'EndTime' => (int) 900,
'U_NB_ChkInDate' => null,
'U_NB_ChkInTime' => null,
'U_NB_ChkOutDate' => null,
'U_NB_ChkOutTime' => null,
'SignData' => null,
'Duration' => (float) 1,
'DurType' => 'H',
'Sched_Closed' => 'N',
'U_NB_TechRate' => (float) 50,
'U_NB_FollowUp' => null,
'[new]' => false,
'[accessible]' => [],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Schedules'
},
(int) 1 => object(App\Model\Entity\Schedule) {
'SrcvCallID' => (int) 361893,
'Line' => (int) 2,
'Technician' => (int) 243,
'StartDate' => object(Cake\I18n\FrozenTime) {
'time' => '2020-03-17 00:00:00.000000-04:00',
'timezone' => 'America/New_York',
'fixedNowTime' => false
},
'StartTime' => (int) 1600,
'EndDate' => object(Cake\I18n\FrozenTime) {
'time' => '2020-03-17 00:00:00.000000-04:00',
'timezone' => 'America/New_York',
'fixedNowTime' => false
},
'EndTime' => (int) 1630,
'U_NB_ChkInDate' => object(Cake\I18n\FrozenTime) {
'time' => '2020-03-17 00:00:00.000000-04:00',
'timezone' => 'America/New_York',
'fixedNowTime' => false
},
'U_NB_ChkInTime' => (int) 1600,
'U_NB_ChkOutDate' => object(Cake\I18n\FrozenTime) {
'time' => '2020-03-17 00:00:00.000000-04:00',
'timezone' => 'America/New_York',
'fixedNowTime' => false
},
'U_NB_ChkOutTime' => (int) 1630,
'SignData' => null,
'Duration' => (float) 30,
'DurType' => 'M',
'Sched_Closed' => 'N',
'U_NB_TechRate' => (float) 150,
'U_NB_FollowUp' => 'Y',
'[new]' => false,
'[accessible]' => [],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Schedules'
}
],
'[new]' => false,
'[accessible]' => [],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Services'
},
]
Опять же, спасибо за любую помощь.