如何使用 TypeORM 查询多对多关系
How to query a Many-to-Many relation with TypeORM
Note
与 Subject
存在多对多关系
查询它的最佳方式是什么?我会喜欢写下下面的内容以获得给定笔记上的所有主题:
const subjectRepo = connection.getRepository(Subject);
const response = await subjectRepo.find({
relations: ['notes'],
where: { note }
});
但是 returns 所有主题,而不仅仅是笔记上的主题。
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"
注意:您可以这样做:
return subjectRepo
.createQueryBuilder('subject')
.leftJoin('subject.notes', 'note')
.where('note.id = :id', { id: note.id })
.getMany();
但我希望有一种字符串更少且显式连接的方法
你试图让TypeORM生成的SQL大致如下
SELECT *
FROM subject
JOIN subject_note AS jt on jt.subject_id = subject.id
WHERE jt.note_id = :id
1。 repo.find
这是不可能的
在撰写本文时,无法使用 repo.find(...)
在联接的 table 上创建 where
子句。您可以 join
(doc) 但 where
子句仅影响存储库的实体。
TypeORM
也会默默地忽略无效的 where 子句,所以要小心那些。
2。重新select注释实体
如果您想要给定 note
的所有 subject
,您将需要使用查询生成器,如您所述,或者您需要重新 select注意对象及其关系。
note = await noteRepo.find({
relations: ['subjects'],
where: { id: note.id }
});
const subjects = note.subjects
3。使用TypeORM
惰性关系
如果你想避免重新selection,你需要使用TypeORM
Lazy relations但是这迫使你将两个实体中的类型更改为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
方法提供关系数组。
const note = await noteRepo.find({
where: { id: someId }
});
const subjects = await note.subjects
Note
与 Subject
查询它的最佳方式是什么?我会喜欢写下下面的内容以获得给定笔记上的所有主题:
const subjectRepo = connection.getRepository(Subject);
const response = await subjectRepo.find({
relations: ['notes'],
where: { note }
});
但是 returns 所有主题,而不仅仅是笔记上的主题。
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"
注意:您可以这样做:
return subjectRepo
.createQueryBuilder('subject')
.leftJoin('subject.notes', 'note')
.where('note.id = :id', { id: note.id })
.getMany();
但我希望有一种字符串更少且显式连接的方法
你试图让TypeORM生成的SQL大致如下
SELECT *
FROM subject
JOIN subject_note AS jt on jt.subject_id = subject.id
WHERE jt.note_id = :id
1。 repo.find
这是不可能的
在撰写本文时,无法使用 repo.find(...)
在联接的 table 上创建 where
子句。您可以 join
(doc) 但 where
子句仅影响存储库的实体。
TypeORM
也会默默地忽略无效的 where 子句,所以要小心那些。
2。重新select注释实体
如果您想要给定 note
的所有 subject
,您将需要使用查询生成器,如您所述,或者您需要重新 select注意对象及其关系。
note = await noteRepo.find({
relations: ['subjects'],
where: { id: note.id }
});
const subjects = note.subjects
3。使用TypeORM
惰性关系
如果你想避免重新selection,你需要使用TypeORM
Lazy relations但是这迫使你将两个实体中的类型更改为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
方法提供关系数组。
const note = await noteRepo.find({
where: { id: someId }
});
const subjects = await note.subjects