在CakePHP3中检索相关数据(hasMany)
我正在尝试检索具有关联票证类型的所有事件:在CakePHP3中检索相关数据(hasMany),cakephp,associations,cakephp-3.0,query-builder,Cakephp,Associations,Cakephp 3.0,Query Builder,我正在尝试检索具有关联票证类型的所有事件: Events hasMany TicketTypes TicketTypes belogsTo Events 生成的SQL查询: $query= $this->Events ->find() ->select(['id', 'name']) ->autoFields(false) ->contain(['TicketTypes' => function($q) {
Events hasMany TicketTypes
TicketTypes belogsTo Events
生成的SQL查询:
$query= $this->Events
->find()
->select(['id', 'name'])
->autoFields(false)
->contain(['TicketTypes' => function($q) {
return $q->select(['TicketTypes.id', 'TicketTypes.name']); }])
;
但我所期望的是:
SELECT Events.id AS `Events__id`, Events.name AS `Events__name` FROM events Events
以下是我的模型的配置方式:
SELECT Events.id AS `Events__id`, Events.name AS `Events__name`, TicketTypes.id AS `TicketTypes__id`, TicketTypes.name AS `TicketTypes__name` FROM events Events LEFT JOIN ticket_types TicketTypes ON Events.id = (TicketTypes.event_id)
以下是调试我的查找查询的结果:
class EventsTable extends Table
{
public function initialize(array $config)
{
$this->displayField('name');
$this->addAssociations([
'hasMany'=> ['TicketTypes']
]);
}
}
class TicketTypesTable extends Table
{
public function initialize(array $config)
{
$this->displayField('name');
$this->addAssociations([
'belongsTo' => ['Events']
]);
}
}
下面是调试$query->all()
的结果:
正如您在这一行中所看到的,'ticket\u types'=>[]
查询不会返回票证类型
如何检索TicketTypes
数据
谢谢。有许多关联正在单独的查询中检索
关于CakePHP ORM如何检索关联数据的假设是不正确的
与在主查询中使用联接的hasOne
和belongsTo
关联不同,hasMany
和belongsToMany
关联数据在单独的查询中检索,该查询使用从主查询中收集的外键值进行过滤,在您的情况下,这将是Events.id
列值
查看SQL日志的其余部分,您会发现一个类似于
选择
TicketTypes.id作为“TicketTypes\uuu id”。。。
从…起
票证类型票证类型
哪里
(1,2,3,…)中的TicketTypes.event_id
该查询的结果将与主结果缝合在一起,并在单个结果集中返回
需要选择外键
第二个问题是containmentsselect()
调用缺少外键列(TicketTypes.event\u id
),这是必需的,没有外键列,ORM无法将结果缝合在一起,因此结果中不会出现票证类型
引用文件:
当您限制从关联中提取的字段时
必须确保选择外键列。未能
选择外键字段将导致关联数据不存在
在最后的结果中
另见
你的问题有点离题,因为你没有详细说明你的实际问题!熟悉CakePHP工作原理的人可能会理解您对什么感到困惑,但StackOverflow不是这样工作的,问题应该明确,这样就没有人会猜到您在问什么。也就是说,使用contain
会导致ORM加载相关的TicketTypes
,这就是您必须做的,也是您已经在做的。如果有具体问题,请提出来。您好,ndm,非常感谢您的评论。请记住,这是我的第一篇文章。我将编辑我的问题,使其更清楚。我已经调试了结果,我期望的数据不在那里object(Cake\ORM\Query){(help)=>“这是一个查询对象,用于获取执行或迭代的结果。”,“sql”=>“选择Events.id作为
Events\uu id,Events.name作为
Events\uu name`FROM Events-Events',`…@danielfuscocicarelo查看(帮助)
key说,您正在查看一个未执行的查询对象,实际上还没有检索到任何内容。您介意看看我的原始问题吗。我添加了debug($query->all);
。谢谢。@dfc您需要在容器中包含外键(TicketTypes.event\u id
)
,否则结果无法缝合在一起,我忽略了这一点。通常情况下,这会触发一个错误,不知道为什么它不再这样做(可能是一个错误,可能是有意更改)…我稍后会更新我的答案。现在我们正在讨论!非常感谢您的帮助和耐心。祝您有愉快的一天!
object(Cake\ORM\Query) {
'(help)' => 'This is a Query object, to get the results execute or iterate it.',
'sql' => 'SELECT Events.id AS `Events__id`, Events.name AS `Events__name` FROM events Events',
'params' => [],
'defaultTypes' => [
'Events.id' => 'integer',
'id' => 'integer',
'Events.name' => 'string',
'name' => 'string',
'Events.datetime_start' => 'datetime',
'datetime_start' => 'datetime',
'Events.datetime_end' => 'datetime',
'datetime_end' => 'datetime',
'Events.created' => 'datetime',
'created' => 'datetime',
'Events.modified' => 'datetime',
'modified' => 'datetime',
'Events.slug' => 'string',
'slug' => 'string',
'TicketTypes.id' => 'integer',
'TicketTypes.event_id' => 'integer',
'event_id' => 'integer',
'TicketTypes.name' => 'string',
'TicketTypes.description' => 'text'
],
'decorators' => (int) 0,
'executed' => false,
'hydrate' => true,
'buffered' => true,
'formatters' => (int) 0,
'mapReducers' => (int) 0,
'contain' => [
'TicketTypes' => [
'queryBuilder' => object(Closure) {
}
]
],
'matching' => [],
'extraOptions' => [],
'repository' => object(App\Model\Table\EventsTable) {
'registryAlias' => 'Events',
'table' => 'events',
'alias' => 'Events',
'entityClass' => 'App\Model\Entity\Event',
'associations' => [
(int) 0 => 'tickettypes'
],
'behaviors' => [],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
}
object(Cake\ORM\ResultSet) {
'items' => [
(int) 0 => object(App\Model\Entity\Event) {
'id' => (int) 101,
'name' => 'qwertyuiop',
'ticket_types' => [],
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Events'
},
...