При работе с отношениями «многие ко многим» в TypeORM обычно загружаются все связанные сущности. Однако в некоторых сценариях вам может потребоваться получить идентификаторы связанных объектов только из соображений производительности. В этой статье мы рассмотрим несколько методов эффективной загрузки только идентификаторов в отношениях «многие-ко-многим» с использованием TypeORM, а также примеры кода для каждого подхода.
Методы загрузки только идентификаторов в отношениях «многие ко многим»:
-
Использование конструктора запросов:
const result = await connection .createQueryBuilder() .select('entity.id', 'id') .from(Entity, 'entity') .leftJoinAndSelect('entity.manyToManyRelation', 'relation') .getRawMany();Этот метод использует построитель запросов для создания запроса, который выбирает только идентификатор объекта и выполняет левое соединение с отношением «многие ко многим». Результатом будет массив объектов со свойством ID.
-
Использование необработанных SQL-запросов:
const result = await connection.query(` SELECT entity.id AS id FROM entity LEFT JOIN manyToManyRelation ON entity.id = manyToManyRelation.entityId `);Написав необработанные SQL-запросы, мы можем напрямую выбрать столбец ID из таблицы сущностей и выполнить левое соединение с отношением «многие ко многим». Результатом будет массив объектов со свойством ID.
-
Использование Entity Manager и метаданных:
const relationMetadata = connection.getMetadata(Entity).relations.find(relation => relation.propertyName === 'manyToManyRelation'); const result = await connection.manager .createQueryBuilder() .relation(Entity, 'manyToManyRelation') .of(entity) .loadRawMany(); const ids = result.map(row => row[relationMetadata.inverseEntityMetadata.primaryColumns[0].propertyName]);Этот метод использует Entity Manager для загрузки отношения «многие ко многим» в виде необработанных данных, а затем извлекает идентификаторы на основе метаданных отношения. Результатом будет массив идентификаторов.
-
Использование собственного метода репозитория:
@EntityRepository(Entity) class EntityRepository extends Repository<Entity> { async loadManyToManyRelationIds(entity: Entity): Promise<number[]> { const relationMetadata = this.metadata.relations.find(relation => relation.propertyName === 'manyToManyRelation'); const result = await this.createQueryBuilder() .relation('manyToManyRelation') .of(entity) .loadRawMany(); return result.map(row => row[relationMetadata.inverseEntityMetadata.primaryColumns[0].propertyName]); } } // Usage: const repository = connection.getCustomRepository(EntityRepository); const ids = await repository.loadManyToManyRelationIds(entity);Этот метод предполагает создание специального репозитория с особым методом для загрузки идентификаторов отношений «многие ко многим». Он использует тот же подход, что и предыдущий метод, но инкапсулирует его в репозиторий для возможности повторного использования.
Используя эти методы, вы можете эффективно загружать в TypeORM только идентификаторы отношений «многие-ко-многим». В зависимости от ваших предпочтений и требований проекта вы можете выбрать метод, который лучше всего соответствует вашим потребностям. При принятии решения о том, какой подход использовать, не забудьте учитывать компромисс между производительностью и сложностью кода.