在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
该查询的结果将与主结果缝合在一起,并在单个结果集中返回

需要选择外键 第二个问题是containments
select()
调用缺少外键列(
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'

        },
    ...