我使用并集来连接两个数据集,然后使用以下查询来设置正确的分页
$paginationQuery = $this->find('all')
->contain(['EmailAddresses' => [
'foreignKey' => false,
'queryBuilder' => function($q) {
return $q->where(['Members__id' => 'EmailAddresses.member_id']);
}
]])
->select( $selectMainUnion )
->from([$this->getAlias() => $query])
->order(['Members__last_name' => 'ASC', 'Members__first_name' => 'ASC']);
我也试过
$paginationQuery = $this->find('all')
->contain(['EmailAddresses'])
->select( $selectMainUnion )
->from([$this->getAlias() => $query])
->order(['Members__last_name' => 'ASC', 'Members__first_name' => 'ASC']);
并尝试$query->loadInto($query,[电子邮件地址](;其中$query是并集的结果。
这两种方法都不会将电子邮件地址添加到$paginationQuery中。
有办法做到这一点吗?
添加以澄清代码
$selectMain =['Members.id',
'Members.member_type',
'Members.first_name',
'Members.middle_name',
'Members.last_name',
'Members.suffix',
'Members.date_joined'];
foreach($selectMain as $select) {
$selectMainUnion[] = str_replace('.', '__', $select);
}
$this->hasMany('EmailAddresses', [
'foreignKey' => 'member_id',
'dependent' => true,
]);
查看DebugKit SQL日志中的SQL,没有引用EmailAddresses表。
通常,无论查询FROM
子句是表还是子查询,容器都可以正常工作。然而,要做到这一点,需要选择所需的主键和/或外键字段,并且它们的格式正确。
默认情况下,CakePHP的ORM查询会自动对所选字段进行别名,即它们像Alias.field AS Alias__field
一样被选中。因此,当Alias
是一个子查询时,那么Alias.field
不存在,您必须选择Alias.Alias__field
。因此,使用自动别名,您对Members__id
的选择将转换为Members.Members__id AS Members__Members__id
,而Members__Members__id
不是ORM所理解的,它在您的实体中最终会变成Members__id
,而热切的加载器会期望id
,即用于注入查询的hasMany
相关记录的结果的主键的名称(这发生在单独的查询中(,您的自定义queryBuilder
对此没有帮助,因为注入之后会在PHP级别上进行。
长话短说,为了解决这个问题,您可以更改联合查询的字段的选择方式,即确保它们不使用别名进行选择,这样就根本不需要更改分页查询字段:
$fields = $table->getSchema()->columns();
$fields = array_combine($fields, $fields);
$query->select($fields);
这将创建一个格式为['id' => 'id', ...]
的字段列表,看起来有点奇怪,但它是有效的(例如,只要没有因联接表而产生的歧义(,SQL将类似于id AS id
,因此您的分页查询可以简单地引用类似Members.id
的字段。
另一种方法是选择子查询的别名,即不仅选择Member__id
,ORM在应用自动别名时将其转换为Member__Member__id
,而且使用Members.Member__id
,如:
[
'Member__id' => 'Members.Member__id',
// ...
]
这样就不会发生自动别名,在SQL级别上,它会选择类似Members.Member__id AS Member__id
的字段,并且该字段在实体中最终会变成id
,热切的加载器会找到它,并可以使用它来注入关联的记录。