本文介绍了如何使用 TypeORM 查询多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

NoteSubject

查询它的最佳方法是什么?我想写以下内容,以便在给定的笔记上记录所有主题:

What is the best way to query it? I would like to write the following to get all the subjects on a give note:

  const subjectRepo = connection.getRepository(Subject);
  const response = await subjectRepo.find({
    relations: ['notes'],
    where: { note }
  });

但这会返回所有主题,而不仅仅是笔记上的主题.

but that returns ALL of the subjects, not just the subjects on the note.

Reln 定义为:

  @ManyToMany(() => Subject, (subject: Subject) => subject.notes)
  subjects: Subject[];

-- 和 --

  @ManyToMany(() => Note, note => note.subjects)
  @JoinTable()
  notes: Note[];

执行的查询是:

SELECT "Subject"."id" AS "Subject_id", "Subject"."name" AS "Subject_name", "Subject"."description" AS "Subject_description", "Subject"."createdDate" AS "Subject_createdDate", "Subject"."updatedDate" AS "Subject_updatedDate", "Subject"."notebookId" AS "Subject_notebookId", "Subject"."measurementsId" AS "Subject_measurementsId", "Subject_notes"."id" AS "Subject_notes_id", "Subject_notes"."content" AS "Subject_notes_content", "Subject_notes"."notedAt" AS "Subject_notes_notedAt", "Subject_notes"."createdDate" AS "Subject_notes_createdDate", "Subject_notes"."updatedDate" AS "Subject_notes_updatedDate", "Subject_notes"."notebookId" AS "Subject_notes_notebookId" FROM "subject" "Subject" LEFT JOIN "subject_notes_note" "Subject_Subject_notes" ON "Subject_Subject_notes"."subjectId"="Subject"."id" LEFT JOIN "note" "Subject_notes" ON "Subject_notes"."id"="Subject_Subject_notes"."noteId"

注意:您可以这样做:


Note: you can do this:

  return subjectRepo
    .createQueryBuilder('subject')
    .leftJoin('subject.notes', 'note')
    .where('note.id = :id', { id: note.id })
    .getMany();

但我希望有一种更少的字符串和显式加入的方法

But I am hoping for an approach with less strings, and explicit joining

推荐答案

你试图让TypeORM生成的SQL大致如下

The SQL you are trying to get TypeORM to generate is roughly as follows

SELECT *
FROM subject
JOIN subject_note AS jt on jt.subject_id = subject.id
WHERE jt.note_id = :id

1.repo.find

无法做到这一点

在撰写本文时,无法使用 repo.find(...) 在连接表上创建 where 子句.您可以加入 (doc) 但 where 子句只影响存储库的实体.

1. This is not possible with repo.find

At the time of writing, there is no way to create a where clause on a joined table using repo.find(...). You can join (doc) but the where clause only affects the entity of the repository.

TypeORM 也会默默地忽略无效的 where 子句,所以要小心那些.

TypeORM also silently ignores invalid where clauses, so be careful about those.

如果您想要给定 note 的所有 subject,您将需要使用查询构建器,就像您指出的那样,或者您需要重新选择注意对象及其关系.

If you want all the subject of a given note, you will either need to use a query builder, like you noted or you will need to re-select the note object with it's relationships.

note = await noteRepo.find({
    relations: ['subjects'],
    where: { id: note.id }
});
const subjects = note.subjects

3.使用 TypeORM 惰性关系

如果你想避免重新选择,你需要使用TypeORM 惰性关系 但这迫使您将两个实体中的类型更改为 Promise

// note entity
@ManyToMany(() => Subject, (subject: Subject) => subject.notes)
subjects: Promise<Subject[]>;

// subject entity
@ManyToMany(() => Note, note => note.subjects)
@JoinTable()
notes: Promise<Note[]>;

使用这种惰性关系,您需要在每次使用之前await 以加载链接的笔记,但您无需为find 方法.

With this lazy relations, you will need to await for the linked notes to load before each usage, but you will not need to provide an array of relations to the find method.

const note = await noteRepo.find({
    where: { id: someId }
});
const subjects = await note.subjects

这篇关于如何使用 TypeORM 查询多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 01:55