From 419d5b4f23efa111f698620e118b7168a1a594bd Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Wed, 18 May 2022 21:57:22 +0200 Subject: [PATCH] perf(query-typeorm): Use existing join alias if there is one --- jest.preset.ts | 8 +- .../relation-query.builder.spec.ts.snap | 34 ++- .../query/relation-query.builder.spec.ts | 12 +- packages/query-typeorm/package.json | 2 +- .../src/query/relation-query.builder.ts | 239 +++++++++--------- .../src/services/relation-query.service.ts | 17 +- 6 files changed, 165 insertions(+), 147 deletions(-) diff --git a/jest.preset.ts b/jest.preset.ts index abbf8a52a..b51aedffb 100644 --- a/jest.preset.ts +++ b/jest.preset.ts @@ -5,7 +5,13 @@ module.exports = { collectCoverage: true, coverageReporters: ['html', 'clover'], - collectCoverageFrom: ['packages/**/*.ts', '!**/__tests__/**', '!**/dist/**', '!**/node_modules/**'], + collectCoverageFrom: [ + 'packages/**/*.ts', + '!**/__tests__/**', + '!**/dist/**', + '!**/node_modules/**', + '!**/jest.config.ts', + ], moduleNameMapper: { '@ptc-org/nestjs-query-core': process.cwd() + '/packages/core/src', '@ptc-org/nestjs-query-graphql': process.cwd() + '/packages/query-graphql/src', diff --git a/packages/query-typeorm/__tests__/query/__snapshots__/relation-query.builder.spec.ts.snap b/packages/query-typeorm/__tests__/query/__snapshots__/relation-query.builder.spec.ts.snap index 662c7643a..cdf912729 100644 --- a/packages/query-typeorm/__tests__/query/__snapshots__/relation-query.builder.spec.ts.snap +++ b/packages/query-typeorm/__tests__/query/__snapshots__/relation-query.builder.spec.ts.snap @@ -7,12 +7,28 @@ SELECT "manyToOneRelation"."test_entity_id" AS "manyToOneRelation_test_entity_id", "manyToOneRelation"."uni_directional_test_entity_id" AS "manyToOneRelation_uni_directional_test_entity_id", "manyToOneRelation"."uni_directional_relation_test_entity_id" AS "manyToOneRelation_uni_directional_relation_test_entity_id", - "TestEntity"."test_entity_pk" AS "TestEntity_test_entity_pk" + "test_entity"."test_entity_pk" AS "test_entity_testEntityPk" FROM "test_relation" "manyToOneRelation" - LEFT JOIN "test_entity" "TestEntity" ON "TestEntity"."many_to_one_relation_id" = "manyToOneRelation"."test_relation_pk" + INNER JOIN "test_entity" "test_entity" ON "test_entity"."many_to_one_relation_id" = "manyToOneRelation"."test_relation_pk" WHERE - "TestEntity"."test_entity_pk" IN (test-entity-id-1, test-entity-id-2) + "test_entity"."test_entity_pk" IN (test-entity-id-1, test-entity-id-2) +`; + +exports[`RelationQueryBuilder #batchSelect should reuse existing join alias if there is one 1`] = ` +SELECT + "manyToOneRelation"."test_relation_pk" AS "manyToOneRelation_test_relation_pk", + "manyToOneRelation"."relation_name" AS "manyToOneRelation_relation_name", + "manyToOneRelation"."test_entity_id" AS "manyToOneRelation_test_entity_id", + "manyToOneRelation"."uni_directional_test_entity_id" AS "manyToOneRelation_uni_directional_test_entity_id", + "manyToOneRelation"."uni_directional_relation_test_entity_id" AS "manyToOneRelation_uni_directional_relation_test_entity_id", + "testEntity"."test_entity_pk" AS "testEntity_testEntityPk" +FROM + "test_relation" "manyToOneRelation" + LEFT JOIN "test_entity" "testEntity" ON "testEntity"."test_entity_pk" = "manyToOneRelation"."test_entity_id" +WHERE + (("testEntity"."test_entity_pk" = test)) + AND "testEntity"."test_entity_pk" IN (test-entity-1) `; exports[`RelationQueryBuilder #select many to many many-to-many custom join table should work with a many-to-many through a join table 1`] = ` @@ -86,9 +102,9 @@ SELECT "testEntityUniDirectional"."oneTestRelationTestRelationPk" AS "testEntityUniDirectional_oneTestRelationTestRelationPk" FROM "test_entity" "testEntityUniDirectional" - INNER JOIN "test_relation" "TestRelation" ON "TestRelation"."uni_directional_test_entity_id" = "testEntityUniDirectional"."test_entity_pk" + INNER JOIN "test_relation" "test_relation" ON "test_relation"."uni_directional_test_entity_id" = "testEntityUniDirectional"."test_entity_pk" WHERE - ("TestRelation"."test_relation_pk" = test-relation-id-1) + ("test_relation"."test_relation_pk" = test-relation-id-1) `; exports[`RelationQueryBuilder #select many to one should work with one entity 1`] = ` @@ -102,9 +118,9 @@ SELECT "testEntity"."oneTestRelationTestRelationPk" AS "testEntity_oneTestRelationTestRelationPk" FROM "test_entity" "testEntity" - INNER JOIN "test_relation" "TestRelation" ON "TestRelation"."test_entity_id" = "testEntity"."test_entity_pk" + INNER JOIN "test_relation" "test_relation" ON "test_relation"."test_entity_id" = "testEntity"."test_entity_pk" WHERE - ("TestRelation"."test_relation_pk" = test-relation-id-1) + ("test_relation"."test_relation_pk" = test-relation-id-1) `; exports[`RelationQueryBuilder #select one to many should query with a single entity 1`] = ` @@ -146,9 +162,9 @@ SELECT "oneTestRelation"."uni_directional_relation_test_entity_id" AS "oneTestRelation_uni_directional_relation_test_entity_id" FROM "test_relation" "oneTestRelation" - INNER JOIN "test_entity" "TestEntity" ON "TestEntity"."oneTestRelationTestRelationPk" = "oneTestRelation"."test_relation_pk" + INNER JOIN "test_entity" "test_entity" ON "test_entity"."oneTestRelationTestRelationPk" = "oneTestRelation"."test_relation_pk" WHERE - ("TestEntity"."test_entity_pk" = test-entity-id-1) + ("test_entity"."test_entity_pk" = test-entity-id-1) `; exports[`RelationQueryBuilder #select with filter should call whereBuilder#build if there is a filter 1`] = ` diff --git a/packages/query-typeorm/__tests__/query/relation-query.builder.spec.ts b/packages/query-typeorm/__tests__/query/relation-query.builder.spec.ts index 210a72ba5..fe6dbd071 100644 --- a/packages/query-typeorm/__tests__/query/relation-query.builder.spec.ts +++ b/packages/query-typeorm/__tests__/query/relation-query.builder.spec.ts @@ -4,6 +4,8 @@ import { closeTestConnection, createTestConnection, getTestConnection } from '.. import { TestRelation } from '../__fixtures__/test-relation.entity'; import { TestEntity } from '../__fixtures__/test.entity'; import { RelationQueryBuilder } from '../../src/query'; +import { TestEntityRelationEntity } from '../__fixtures__/test-entity-relation.entity'; +import { TEST_ENTITIES, TEST_RELATIONS } from '../__fixtures__/seeds'; describe('RelationQueryBuilder', (): void => { beforeEach(createTestConnection); @@ -196,13 +198,17 @@ describe('RelationQueryBuilder', (): void => { } ]; - describe('many to one', () => { - // TODO:: SQL is updated, now make sure that batchQueryRelations keeps working + it('should reuse existing join alias if there is one', () => { + const query: Query = { filter: { testEntity: { testEntityPk: { eq: 'test' } } } }; + + const entities = TEST_ENTITIES.slice(0, 1); + expectBatchSQLSnapshot(TestEntity, entities, 'manyToOneRelation', query); + }); + describe('many to one', () => { it('should query with with multiple entities', () => { expectBatchSQLSnapshot(TestEntity, testEntities, 'manyToOneRelation', {}); }); - }); }); diff --git a/packages/query-typeorm/package.json b/packages/query-typeorm/package.json index 19627de4f..aaf09204f 100644 --- a/packages/query-typeorm/package.json +++ b/packages/query-typeorm/package.json @@ -1,6 +1,6 @@ { "name": "@ptc-org/nestjs-query-typeorm", - "version": "1.0.0-alpha.2", + "version": "1.0.0-alpha.3", "description": "Typeorm adapter for @ptc-org/nestjs-query-core", "author": "doug-martin ", "homepage": "https://github.com/tripss/nestjs-query#readme", diff --git a/packages/query-typeorm/src/query/relation-query.builder.ts b/packages/query-typeorm/src/query/relation-query.builder.ts index 674c317eb..dfe8c2f93 100644 --- a/packages/query-typeorm/src/query/relation-query.builder.ts +++ b/packages/query-typeorm/src/query/relation-query.builder.ts @@ -3,6 +3,8 @@ import { AggregateQuery, Class, Query } from '@ptc-org/nestjs-query-core'; import { Repository, SelectQueryBuilder, ObjectLiteral, Brackets } from 'typeorm'; import { RelationMetadata } from 'typeorm/metadata/RelationMetadata'; import { DriverUtils } from 'typeorm/driver/DriverUtils'; +import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata'; +import { Alias } from 'typeorm/query-builder/Alias'; import { FilterQueryBuilder } from './filter-query.builder'; import { AggregateBuilder } from './aggregate.builder'; import lodashFilter from 'lodash.filter'; @@ -64,14 +66,22 @@ export type EntityIndexRelation = Relation & { * Class that will convert a Query into a `typeorm` Query Builder. */ export class RelationQueryBuilder { - private relationMetadata: RelationQuery | undefined; readonly filterQueryBuilder: FilterQueryBuilder; readonly relationRepo: Repository; + private relationMetadata: RelationQuery | undefined; + private paramCount: number; + /** + * Will be filled if the query builder already contains the join + * + * TODO:: Do this different? Maybe cleanup the batchSelect / whereCondition as its almost the same + */ + private existingAlias: Alias; + constructor(readonly repo: Repository, readonly relation: string) { this.relationRepo = this.repo.manager.getRepository(this.relationMeta.from); this.filterQueryBuilder = new FilterQueryBuilder(this.relationRepo); @@ -163,6 +173,7 @@ export class RelationQueryBuilder { // many-to-many non owner this.relationMetadata = this.getManyToManyNotOwnerMetadata(relation); } + return this.relationMetadata; } @@ -192,35 +203,33 @@ export class RelationQueryBuilder { } private createRelationQueryBuilder(entity: Entity): SelectQueryBuilder { - const meta = this.relationMeta; - const queryBuilder = this.relationRepo.createQueryBuilder(meta.fromAlias); + const queryBuilder = this.relationRepo.createQueryBuilder(this.relationMeta.fromAlias); - const joinedBuilder = meta.joins.reduce((qb, join) => { + const joinedBuilder = this.relationMeta.joins.reduce((qb, join) => { const conditions = join.conditions.map(({ leftHand, rightHand }) => `${leftHand} = ${rightHand}`); + return qb.innerJoin(join.target, join.alias, conditions.join(' AND ')); }, queryBuilder); return joinedBuilder.where(new Brackets((bqb) => { - const where = meta.whereCondition(entity); + const where = this.relationMeta.whereCondition(entity); bqb.andWhere(where.sql, where.params); })); } private getManyToOneOrOneToOneOwnerMeta(relation: RelationMetadata): RelationQuery { - const aliasName = relation.entityMetadata.name; - const { primaryColumns } = relation.entityMetadata; - const { joinColumns } = relation; - const joins: JoinColumn[] = [ - { - target: relation.entityMetadata.target as Class, - alias: aliasName, - conditions: joinColumns.map((joinColumn) => ({ - leftHand: `${aliasName}.${joinColumn.propertyName}`, - rightHand: `${relation.propertyName}.${joinColumn.referencedColumn!.propertyName}` - })) - } - ]; + const aliasName = relation.entityMetadata.tableName; + + const joins: JoinColumn[] = [{ + target: relation.entityMetadata.target as Class, + alias: aliasName, + conditions: relation.joinColumns.map((joinColumn) => ({ + leftHand: `${aliasName}.${joinColumn.propertyName}`, + rightHand: `${relation.propertyName}.${joinColumn.referencedColumn!.propertyName}` + })) + }]; + const fromPrimaryKeys = relation.inverseEntityMetadata.primaryColumns.map((pk) => ({ selectPath: `${relation.propertyName}.${pk.propertyName}`, databasePath: pk.databasePath, @@ -235,14 +244,13 @@ export class RelationQueryBuilder { joins, mapRelations: (entity: Entity, relations: Relation[], rawRelations: any[]): Relation[] => { - const rawFilter = primaryColumns.reduce((columns, column) => ({ + // Set the alias to use for the join + const joinAlias = this.existingAlias?.name || aliasName; + + const rawFilter = relation.entityMetadata.primaryColumns.reduce((columns, column) => ({ ...columns, - [DriverUtils.buildAlias( - this.relationRepo.manager.connection.driver, - aliasName, - column.databasePath - )]: column.getEntityValue(entity) + [`${joinAlias}_${column.propertyPath}`]: column.getEntityValue(entity) }), {} as Partial); // First filter the raw relations with the PK of the entity, then filter the relations @@ -259,37 +267,46 @@ export class RelationQueryBuilder { }, batchSelect: (qb, entities) => { - const joinCondition = joinColumns.map((column) => { - return `${aliasName}.${column.propertyName} = ${relation.propertyName}.${column.referencedColumn!.propertyName}`; - }).join(' AND '); + this.existingAlias = qb.expressionMap.aliases.find((alias) => { + return alias.type === 'join' && alias.target === relation.entityMetadata.target; + }); + + // Set the alias to use for the join + const joinAlias = this.existingAlias?.name || aliasName; const whereParams = {}; - const whereCondition = primaryColumns.map((column) => { - const paramName = this.getParamName(aliasName); + const whereCondition = relation.entityMetadata.primaryColumns.map((column) => { + const paramName = this.getParamName(joinAlias); whereParams[paramName] = entities.map((entity) => column.getEntityValue(entity)); // Also select the columns, so we can use them to map later - qb.addSelect(`${aliasName}.${column.propertyPath}`) + qb.addSelect(`${joinAlias}.${column.propertyPath}`, `${joinAlias}_${column.propertyPath}`); - return `${aliasName}.${column.propertyPath} IN (:...${paramName})`; + return `${joinAlias}.${column.propertyPath} IN (:...${paramName})`; }).join(' AND '); - return qb.leftJoin(relation.entityMetadata.target as Class, aliasName, joinCondition) - .andWhere(whereCondition, whereParams); + // Only add the joins if there was not an existing one yet for this relation + if (!this.existingAlias) { + qb = joins.reduce((qb, join) => { + const conditions = join.conditions.map(({ leftHand, rightHand }) => `${leftHand} = ${rightHand}`); + + return qb.innerJoin(join.target, join.alias, conditions.join(' AND ')); + }, qb); + } + + return qb.andWhere(whereCondition, whereParams); }, whereCondition: (entity: Entity): SQLFragment => { const params: ObjectLiteral = {}; - const sql = primaryColumns - .map((column) => { - const paramName = this.getParamName(aliasName); + const sql = relation.entityMetadata.primaryColumns.map((column) => { + const paramName = this.getParamName(aliasName); - params[paramName] = column.getEntityValue(entity); - return `${aliasName}.${column.propertyPath} = :${paramName}`; - }) - .join(' AND '); + params[paramName] = column.getEntityValue(entity); + return `${aliasName}.${column.propertyPath} = :${paramName}`; + }).join(' AND '); return { sql, params }; } @@ -304,6 +321,7 @@ export class RelationQueryBuilder { databasePath: pk.databasePath, propertyName: pk.propertyName })); + return { relation, from: relation.inverseRelation!.entityMetadata.target as Class, @@ -318,17 +336,17 @@ export class RelationQueryBuilder { return lodashFilter(relations, filter) as Relation[]; }, - batchSelect: (qb, entities: Entity[]) => { + batchSelect: (qb: SelectQueryBuilder, entities: Entity[]) => { const params = {}; - const sql = columns.map((column) => { + const where = columns.map((column) => { const paramName = this.getParamName(aliasName); params[paramName] = entities.map((entity) => column.referencedColumn!.getEntityValue(entity)); return `${aliasName}.${column.propertyPath} IN (:...${paramName})`; }).join(' AND '); - return qb.andWhere(sql, params); + return qb.andWhere(where, params); }, whereCondition: (entity: Entity): SQLFragment => { const params: ObjectLiteral = {}; @@ -373,44 +391,17 @@ export class RelationQueryBuilder { joins, mapRelations: (entity: Entity, relations: Relation[], rawRelations: RawRelation[]): Relation[] => { - const rawFilter = relation.joinColumns.reduce((columns, column) => ({ - ...columns, - - [`${joinAlias}_${column.propertyName}`]: column.referencedColumn.getEntityValue(entity) - }), {} as Partial); - - // First filter the raw relations with the PK of the entity, then filter the relations - // with the PK of the raw relation - return lodashFilter(rawRelations, rawFilter).reduce((entityRelations, rawRelation) => { - const filter = this.getRelationPrimaryKeysPropertyNameAndColumnsName().reduce((columns, column) => ({ - ...columns, - [column.propertyName]: rawRelation[column.columnName] - }), {} as Partial); - - return entityRelations.concat(lodashFilter(relations, filter) as any); - }, [] as Relation[]); + return this.batchMapRelationsManyToMany( + joinAlias, + relation.joinColumns, + entity, + relations, + rawRelations + ); }, batchSelect: (qb, entities: Entity[]) => { - const params = {}; - - const sql = relation.joinColumns.map((column) => { - const paramName = this.getParamName(column.propertyName); - params[paramName] = entities.map((entity) => column.referencedColumn!.getEntityValue(entity)); - - // We also want to select the field, so we can map them back in the mapper - qb.addSelect(`${joinAlias}.${column.propertyName}`, `${joinAlias}_${column.propertyName}`) - - return `${joinAlias}.${column.propertyName} IN (:...${paramName})`; - }).join(' AND '); - - // Add the needed joins - return joins.reduce((qb, join) => { - const conditions = join.conditions.map(({ leftHand, rightHand }) => `${leftHand} = ${rightHand}`); - - return qb.innerJoin(join.target, join.alias, conditions.join(' AND ')); - }, qb) - .andWhere(sql, params); + return this.batchSelectManyToMany(qb, entities, joinAlias, relation.joinColumns); }, whereCondition: (entity: Entity): SQLFragment => { @@ -432,12 +423,12 @@ export class RelationQueryBuilder { private getManyToManyNotOwnerMetadata(relation: RelationMetadata): RelationQuery { const mainAlias = relation.propertyName; - const joinAlias = relation.junctionEntityMetadata!.tableName; + const joinAlias = relation.junctionEntityMetadata.tableName; const joins = [ { target: joinAlias, alias: joinAlias, - conditions: relation.inverseRelation!.joinColumns.map((joinColumn) => ({ + conditions: relation.inverseRelation.joinColumns.map((joinColumn) => ({ leftHand: `${joinAlias}.${joinColumn.propertyName}`, rightHand: `${mainAlias}.${joinColumn.referencedColumn!.propertyName}` })) @@ -458,44 +449,17 @@ export class RelationQueryBuilder { joins, mapRelations: (entity: Entity, relations: Relation[], rawRelations: RawRelation[]): Relation[] => { - const rawFilter = relation.inverseRelation!.inverseJoinColumns.reduce((columns, column) => ({ - ...columns, - - [`${joinAlias}_${column.propertyName}`]: column.referencedColumn.getEntityValue(entity) - }), {} as Partial); - - // First filter the raw relations with the PK of the entity, then filter the relations - // with the PK of the raw relation - return lodashFilter(rawRelations, rawFilter).reduce((entityRelations, rawRelation) => { - const filter = this.getRelationPrimaryKeysPropertyNameAndColumnsName().reduce((columns, column) => ({ - ...columns, - [column.propertyName]: rawRelation[column.columnName] - }), {} as Partial); - - return entityRelations.concat(lodashFilter(relations, filter) as any); - }, [] as Relation[]); + return this.batchMapRelationsManyToMany( + joinAlias, + relation.inverseRelation.inverseJoinColumns, + entity, + relations, + rawRelations + ); }, - batchSelect: (qb, entities: Entity[]) => { - const params = {}; - - const sql = relation.inverseRelation!.inverseJoinColumns.map((column) => { - const paramName = this.getParamName(column.propertyName); - params[paramName] = entities.map((entity) => column.referencedColumn!.getEntityValue(entity)); - - // We also want to select the field, so we can map them back in the mapper - qb.addSelect(`${joinAlias}.${column.propertyName}`, `${joinAlias}_${column.propertyName}`) - - return `${joinAlias}.${column.propertyName} IN (:...${paramName})`; - }).join(' AND '); - - // Add the needed joins - return joins.reduce((qb, join) => { - const conditions = join.conditions.map(({ leftHand, rightHand }) => `${leftHand} = ${rightHand}`); - - return qb.innerJoin(join.target, join.alias, conditions.join(' AND ')); - }, qb) - .andWhere(sql, params); + batchSelect: (qb: SelectQueryBuilder, entities: Entity[]): SelectQueryBuilder => { + return this.batchSelectManyToMany(qb, entities, joinAlias, relation.inverseRelation.inverseJoinColumns); }, whereCondition: (entity: Entity): SQLFragment => { @@ -514,8 +478,49 @@ export class RelationQueryBuilder { }; } + private batchSelectManyToMany(qb: SelectQueryBuilder, entities: Entity[], joinAlias: string, columns: ColumnMetadata[],) { + const params = {}; + + const sql = columns.map((column) => { + const paramName = this.getParamName(column.propertyName); + params[paramName] = entities.map((entity) => column.referencedColumn.getEntityValue(entity)); + + // We also want to select the field, so we can map them back in the mapper + qb.addSelect(`${joinAlias}.${column.propertyName}`, `${joinAlias}_${column.propertyName}`); + + return `${joinAlias}.${column.propertyName} IN (:...${paramName})`; + }).join(' AND '); + + // Add the needed joins + return this.relationMeta.joins.reduce((qb, join) => { + const conditions = join.conditions.map(({ leftHand, rightHand }) => `${leftHand} = ${rightHand}`); + + return qb.innerJoin(join.target, join.alias, conditions.join(' AND ')); + }, qb).andWhere(sql, params); + } + + private batchMapRelationsManyToMany(joinAlias: string, columns: ColumnMetadata[], entity: Entity, relations: Relation[], rawRelations: RawRelation[]): Relation[] { + const rawFilter = columns.reduce((columns, column) => ({ + ...columns, + + [`${joinAlias}_${column.propertyName}`]: column.referencedColumn.getEntityValue(entity) + }), {} as Partial); + + // First filter the raw relations with the PK of the entity, then filter the relations + // with the PK of the raw relation + return lodashFilter(rawRelations, rawFilter).reduce((entityRelations, rawRelation) => { + const filter = this.getRelationPrimaryKeysPropertyNameAndColumnsName().reduce((columns, column) => ({ + ...columns, + [column.propertyName]: rawRelation[column.columnName] + }), {} as Partial); + + return entityRelations.concat(lodashFilter(relations, filter) as Relation[]); + }, [] as Relation[]); + } + private getParamName(prefix: string): string { this.paramCount += 1; + return `${prefix}_${this.paramCount}`; } @@ -535,7 +540,7 @@ export class RelationQueryBuilder { return this.relationRepo.manager.connection.driver.escape(str); } - public getRelationPrimaryKeysPropertyNameAndColumnsName(): { columnName: string; propertyName: string }[] { + private getRelationPrimaryKeysPropertyNameAndColumnsName(): { columnName: string; propertyName: string }[] { return this.relationMeta.fromPrimaryKeys.map((pk) => ({ propertyName: pk.propertyName, columnName: DriverUtils.buildAlias( diff --git a/packages/query-typeorm/src/services/relation-query.service.ts b/packages/query-typeorm/src/services/relation-query.service.ts index ed136f792..9056f41e6 100644 --- a/packages/query-typeorm/src/services/relation-query.service.ts +++ b/packages/query-typeorm/src/services/relation-query.service.ts @@ -333,9 +333,9 @@ export abstract class RelationQueryService { query: Query ): Promise> { const assembler = AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName)); - const relationQueryBuilder = this.getRelationQueryBuilder(relationName); const convertedQuery = assembler.convertQuery(query); + const relationQueryBuilder = this.getRelationQueryBuilder(relationName); const entityRelations = await relationQueryBuilder.batchSelect(entities, convertedQuery).getRawAndEntities(); return entities.reduce((results, entity) => { @@ -460,21 +460,6 @@ export abstract class RelationQueryService { return relationMeta.type as Class; } - private getRelationsFromPrimaryKeys( - relationBuilder: RelationQueryBuilder, - rawResult: ObjectLiteral, - relations: Relation[] - ): Relation[] { - const pks = relationBuilder.getRelationPrimaryKeysPropertyNameAndColumnsName(); - const filter = pks.reduce( - (keys, key) => - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - ({ ...keys, [key.propertyName]: rawResult[key.columnName] }), - {} as Partial - ); - return lodashFilter(relations, filter) as Relation[]; - } - private getRelations( relationName: string, ids: (string | number)[],