* Adds a JOIN clause and automatically selects the joined entity's fields. * This is useful for eager loading related entities. * * @example * ```ts * const qb = em.createQueryBuilder(Book, 'b'); * qb.select('*') * .joinAndSelect('b.author', 'a') * .where({ 'a.name': 'Joh
(
field: Field | [Field, RawQueryFragment | QueryBuilder<any>],
alias: Alias,
cond: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias> = {} as JoinCondition<
JoinedEntityType<Entity, Context, Field & string>,
Alias
>,
type = JoinType.innerJoin,
path?: string,
fields?: JoinFields,
schema?: string,
)
| 1170 | * ``` |
| 1171 | */ |
| 1172 | joinAndSelect< |
| 1173 | Field extends QBField<Entity, RootAlias, Context>, |
| 1174 | Alias extends string, |
| 1175 | const JoinFields extends |
| 1176 | | readonly [ |
| 1177 | JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, |
| 1178 | ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[], |
| 1179 | ] |
| 1180 | | undefined = undefined, |
| 1181 | >( |
| 1182 | field: Field | [Field, RawQueryFragment | QueryBuilder<any>], |
| 1183 | alias: Alias, |
| 1184 | cond: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias> = {} as JoinCondition< |
| 1185 | JoinedEntityType<Entity, Context, Field & string>, |
| 1186 | Alias |
| 1187 | >, |
| 1188 | type = JoinType.innerJoin, |
| 1189 | path?: string, |
| 1190 | fields?: JoinFields, |
| 1191 | schema?: string, |
| 1192 | ): SelectQueryBuilder< |
| 1193 | Entity, |
| 1194 | RootAlias, |
| 1195 | ModifyHint<RootAlias, Context, Hint, Field, true> & {}, |
| 1196 | ModifyContext<Entity, Context, Field, Alias, true>, |
| 1197 | RawAliases, |
| 1198 | ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, |
| 1199 | CTEs |
| 1200 | > { |
| 1201 | if (!this.#state.type) { |
| 1202 | this.select('*'); |
| 1203 | } |
| 1204 | |
| 1205 | let subquery: string | undefined; |
| 1206 | |
| 1207 | if (Array.isArray(field)) { |
| 1208 | const rawFragment = field[1] instanceof QueryBuilder ? field[1].toRaw() : field[1]; |
| 1209 | subquery = this.platform.formatQuery(rawFragment.sql, rawFragment.params); |
| 1210 | field = field[0]; |
| 1211 | } |
| 1212 | |
| 1213 | const { prop, key } = this.joinReference(field as string, alias, cond, type, path, schema, subquery); |
| 1214 | const [fromAlias] = this.helper.splitField(field as string as EntityKey<Entity>); |
| 1215 | |
| 1216 | if (subquery) { |
| 1217 | this.#state.joins[key].subquery = subquery; |
| 1218 | } |
| 1219 | |
| 1220 | const populate = this.#state.joinedProps.get(fromAlias); |
| 1221 | const item = { field: prop.name, strategy: LoadStrategy.JOINED, children: [] }; |
| 1222 | |
| 1223 | if (populate) { |
| 1224 | populate.children!.push(item); |
| 1225 | } else { |
| 1226 | // root entity |
| 1227 | this.#state.populate.push(item); |
| 1228 | } |
| 1229 |
no test coverage detected