如何 select 包含关联的字段?

How to select fields of a contained association?

我想执行以下查询,我只想从关联中读取必要的字段。
我在下面的 select() 中使用了点符号来更好地解释我想要的内容。
基本上 select() 似乎只涉及 Users。是否可以指定Sites的字段?

$orders = $this->Orders->find()
    ->contain([
        'Sites.Users'=> function ($q) {
            return $q
                ->select([
                    'Sites.id',
                    'Sites.user_id',
                    'Users.id',
                    'Users.name',
                    'Users.owner_id',
                    'Users.firstname',
                    'Users.lastname'
                ])
                ->autoFields(false);
        },
    ])
    ->first();

您必须单独配置包含,select设置其他包含的字段将不起作用。

确切地说,除了相应的包含配置之外,您不能从任何其他地方为包含字段 select,唯一的例外是 belongsTo/hasOne 使用连接策略的关联,它们的字段可以在即时 "parent" 查询的 select() 调用中 selected,因为这些关联将通过该查询中的联接检索。

例如,如果 Sites 是一个 belongsTo 关联,那么您可以通过对 Ordersselect() 调用来 select 它的字段。如果 UsersbelongsTo,但 SiteshasMany,那么您可以使用 select() 调用 Sites 到 select Users.

字段

也就是说,在您的情况下,您可以使用 queryBuilder 选项在嵌套数组结构中定义回调

contain([
    'Sites' => [
        'queryBuilder' => function ($q) {
            return $q
                ->select([
                    'Sites.id',
                    'Sites.user_id'
                ]);
        },
        'Users' => function ($q) {
            return $q
                ->select([
                    'Users.id',
                    'Users.name',
                    'Users.owner_id',
                    'Users.firstname',
                    'Users.lastname'
                ]);
        }
    ]
])

或者,如果您实际上不需要查询构建器,请使用 fields 选项

contain([
    'Sites' => [
        'fields' => [
            'Sites.id',
            'Sites.user_id'
        ],
        'Users' => [
            'fields' => [
                'Users.id',
                'Users.name',
                'Users.owner_id',
                'Users.firstname',
                'Users.lastname'
            ]
        ]
    ]
])

另见