Note
a une relation plusieurs-à-plusieurs avec Subject
Quelle est la meilleure façon de l'interroger? Je voudrais aimer écrire ce qui suit pour obtenir tous les sujets sur une note :
const subjectRepo = connection.getRepository(Subject);
const response = await subjectRepo.find({
relations: ['notes'],
where: { note }
});
mais cela renvoie TOUS les sujets, pas seulement les sujets sur la note.
Reln défini comme:
@ManyToMany(() => Subject, (subject: Subject) => subject.notes)
subjects: Subject[];
-- et --
@ManyToMany(() => Note, note => note.subjects)
@JoinTable()
notes: Note[];
La requête exécutée est:
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"
Remarque: vous pouvez le faire:
return subjectRepo
.createQueryBuilder('subject')
.leftJoin('subject.notes', 'note')
.where('note.id = :id', { id: note.id })
.getMany();
Mais j'espère une approche avec moins de chaînes et une jointure explicite
Le SQL que vous essayez d'obtenir pour générer TypeORM est à peu près comme suit
SELECT *
FROM subject
JOIN subject_note AS jt on jt.subject_id = subject.id
WHERE jt.note_id = :id
repo.find
Au moment de l'écriture, il n'y a aucun moyen de créer une clause where
sur une table jointe à l'aide de repo.find(...)
. Vous pouvez join
( doc ) mais la clause where
affecte uniquement l'entité du référentiel.
TypeORM
ignore également silencieusement les clauses where invalides, alors faites attention à celles-ci.
Si vous voulez tous les subject
d'un note
donné, vous devrez soit utiliser un générateur de requêtes, comme vous l'avez noté, soit vous devrez resélectionner l'objet note avec ses relations.
note = await noteRepo.find({
relations: ['subjects'],
where: { id: note.id }
});
const subjects = note.subjects
TypeORM
relations paresseusesSi vous voulez éviter une nouvelle sélection, vous devez utiliser TypeORM
relations paresseuses mais cela vous oblige à changer le type dans les deux entités pour être un Promise
// note entity
@ManyToMany(() => Subject, (subject: Subject) => subject.notes)
subjects: Promise<Subject[]>;
// subject entity
@ManyToMany(() => Note, note => note.subjects)
@JoinTable()
notes: Promise<Note[]>;
Avec ces relations paresseuses, vous devrez await
pour que les notes liées se chargent avant chaque utilisation, mais vous n'aurez pas besoin de fournir un tableau de relations à la méthode find
.
const note = await noteRepo.find({
where: { id: someId }
});
const subjects = await note.subjects