CakePHP 3 使用 ORM 加入辅助键
CakePHP 3 join on a secondary key using ORM
CakePHP 3.5.13 - 使用遗留数据库。我有一个名为 substances
的 table,其中主键是 id
。此 table 中还有另一列名为 app_id
。
应用程序中的大多数 table 都有一个外键,这意味着它们可以连接到 substances.id
。有一个名为 article_95
的 table,它有一个字段 article_95.app_id
,因此必须对 substances.app_id
进行连接(而不是 substances.id
- 没有引用article_95
table 里面的字段。
应用程序最多可根据 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
table 时,我的问题在于如何操作查询对象,因为它试图在 substances.id
上加入,而我需要它加入 substances.app_id
.
我的 Table
类 中有以下内容。请注意行 $this->setPrimaryKey('tbl_id');
- 这是因为我使用的是 legacy/old 数据库并且 article_95
table 的主键实际上是 tbl_id
而不是 id
。然而,这相对无关紧要,因为连接应该基于 table 中存在的 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'
]);
}
如果我尝试执行包含第 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
上保持连接也很重要。
有人可以帮忙吗?
manual解释一切
属于
bindingKey: The name of the column in the other table, that will be used for matching the foreignKey. If not specified, the primary key (for example the id column of the Users table) will be used.
$this->belongsTo('Substances', [
'foreignKey' => 'app_id',
'bindingKey' => 'app_id',
'joinType' => 'INNER'
]);
有很多
bindingKey: The name of the column in the current table, that will be used for matching the foreignKey. If not specified, the primary key (for example the id column of the Articles table) will be used.
$this->hasMany('Article95s', [
'foreignKey' => 'app_id',
'bindingKey' => 'app_id',
]);
CakePHP 3.5.13 - 使用遗留数据库。我有一个名为 substances
的 table,其中主键是 id
。此 table 中还有另一列名为 app_id
。
应用程序中的大多数 table 都有一个外键,这意味着它们可以连接到 substances.id
。有一个名为 article_95
的 table,它有一个字段 article_95.app_id
,因此必须对 substances.app_id
进行连接(而不是 substances.id
- 没有引用article_95
table 里面的字段。
应用程序最多可根据 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
table 时,我的问题在于如何操作查询对象,因为它试图在 substances.id
上加入,而我需要它加入 substances.app_id
.
我的 Table
类 中有以下内容。请注意行 $this->setPrimaryKey('tbl_id');
- 这是因为我使用的是 legacy/old 数据库并且 article_95
table 的主键实际上是 tbl_id
而不是 id
。然而,这相对无关紧要,因为连接应该基于 table 中存在的 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'
]);
}
如果我尝试执行包含第 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
上保持连接也很重要。
有人可以帮忙吗?
manual解释一切
属于
bindingKey: The name of the column in the other table, that will be used for matching the foreignKey. If not specified, the primary key (for example the id column of the Users table) will be used.
$this->belongsTo('Substances', [
'foreignKey' => 'app_id',
'bindingKey' => 'app_id',
'joinType' => 'INNER'
]);
有很多
bindingKey: The name of the column in the current table, that will be used for matching the foreignKey. If not specified, the primary key (for example the id column of the Articles table) will be used.
$this->hasMany('Article95s', [
'foreignKey' => 'app_id',
'bindingKey' => 'app_id',
]);