CakePHP 3 присоединяется к вторичному ключу, используя ORM - PullRequest
0 голосов
/ 29 мая 2018

CakePHP 3.5.13 - работа с устаревшей базой данных.У меня есть таблица с именем substances, где первичный ключ - id.В этой таблице также есть еще один столбец с именем app_id.

Большинство таблиц в приложении имеют внешний ключ, что означает, что они могут быть присоединены к substances.id.Существует одна таблица с именем article_95, которая имеет поле article_95.app_id, и поэтому соединение должно быть выполнено для substances.app_id (не substances.id - в таблице article_95 вообще нет ссылки на это поле).

Приложение выполняет поиск на основе до 11 входов.Я использую ORM для динамического построения объекта запроса перед его выполнением.

Я начинаю свой запрос следующим образом:

$query = $Substances->find()->select(['id' => 'Substances.id'])->distinct();

Затем, если я хочу сделать что-то, где соединение сопоставляется сsubstances.id, я делаю это так:

// Search by CAS Number
if ($this->request->getData('cas_number')) {
    $cas_number = $this->request->getData('cas_number');
    $query = $query->matching('Cas', function ($q) use ($cas_number) {
        return $q->where([
            'Cas.value LIKE' => '%'.$cas_number.'%'
        ]);
    });
}

Пока все хорошо.Если я выведу строку SQL, она будет выглядеть следующим образом:

'SELECT DISTINCT Substances.id AS `id` FROM substances Substances INNER JOIN cas_substances CasSubstances ON Substances.id = (CasSubstances.substance_id) INNER JOIN cas Cas ON (Cas.value like :c0 AND Cas.id = (CasSubstances.cas_id))'

Моя проблема связана с тем, как манипулировать объектом запроса, когда дело доходит до моей таблицы article_95, потому что он пытается присоединиться к substances.id, когдаМне нужно, чтобы он присоединился к substances.app_id.

У меня есть следующее в моих Table классах.Обратите внимание на строку $this->setPrimaryKey('tbl_id'); - это потому, что я использую устаревшую / старую базу данных, а первичный ключ таблицы article_95 на самом деле tbl_id, а не id.Однако это относительно незначительно, потому что объединение должно основываться на app_id, который существует в обеих таблицах.

// src/Model/Table/SubstancesTable.php
public function initialize(array $config)
{
    $this->setTable('substances');
    $this->setPrimaryKey('id');
    $this->hasMany('Article95s', [
        'foreignKey' => 'app_id'
    ]);
    // ...
}


// src/Model/Table/Article95sTable.php
public function initialize(array $config)
{
    $this->setTable('article_95');
    $this->setPrimaryKey('tbl_id');

    $this->belongsTo('Substances', [
        'foreignKey' => 'app_id',
        'joinType' => 'INNER'
    ]);
}

Если я попытаюсь выполнить поиск, который включает в себя значение Article 95, строка SQL становится такой:

'SELECT DISTINCT Substances.id AS `id` FROM substances Substances INNER JOIN cas_substances CasSubstances ON Substances.id = (CasSubstances.substance_id) INNER JOIN cas Cas ON (Cas.value like :c0 AND Cas.id = (CasSubstances.cas_id)) INNER JOIN article_95 Article95s ON (Article95s.entity_name like :c1 AND Substances.id = (Article95s.app_id))'

Проблема в том, что это часть строки SQL, которая читает Substances.id = (Article95s.app_id)).Мне нужно, чтобы это было Substances.app_id = (Article95s.app_id)), но я не знаю, как написать это с помощью синтаксиса ORM.

Также важно, чтобы остальные соединения (например, номер CAS, показанные ранее) оставались объединенными на substances.id.

Может кто-нибудь помочь?

1 Ответ

0 голосов
/ 29 мая 2018

руководство все объяснить

относится к

bindingKey : имя столбца в другая таблица , которая будет использоваться для сопоставления foreignKey.Если не указан, будет использоваться первичный ключ (например, столбец id таблицы Users).

$this->belongsTo('Substances', [
    'foreignKey' => 'app_id',
    'bindingKey' => 'app_id',
    'joinType' => 'INNER'
]);

hasMany

bindingKey : Имя столбца в текущей таблице , который будет использоваться для сопоставления foreignKey.Если не указан, будет использоваться первичный ключ (например, столбец id таблицы Articles).

$this->hasMany('Article95s', [
    'foreignKey' => 'app_id',
    'bindingKey' => 'app_id',
]);
...