'How to bind multiple entites in a many-to-many relation with a single operation using TypeORM

I've been using TypeORM for a while, but I really struggle with their docs sometimes, so I'm sorry if this is somewhat obvious. I have a many-to-many relation that's setup like this:

@Entity()
class Class {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany(() => Course, course => course.classes)
  @JoinTable(/* ... */)
  courses: Course[];

  // ...
}

@Entity()
class Course {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany(() => Class, classObj => classObj.courses)
  classes: Class[];

  // ...
}

And I need to bind multiple classes with multiple courses. I've tried using a repository:

addCoursesToClasses(classIds: string[], courseIds: string[]): void {
  // ormRepository = getRepository(Class)
  await this.ormRepository.update(classIds, {
    courses: courseIds.map(courseId => ({ id: courseId })),
  });
}

But that gives me an error: Cannot query across many-to-many for property courses. I also know it's possible to do something like:

addCoursesToClasses(classIds: string[], courseIds: string[]): void {
  classIds.forEach(classId => {
    courseIds.forEach(courseId => {
      this.ormRepository
        .createQueryBuilder()
        .relation(Class, 'courses')
        .of(classId)
        .add(courseId);
    });
  });
}

But that's, well, suboptimal. I'd really like to do this with a single query because I may have dozens of classes being related to *a lot* of courses at the same time and that may add up to even more than 200 individual queries per request, it's just a waste of network resources and if something happens in the middle of the way (the connection is lost for example) it'll be expensive to reconcile data.

My current solution is just assembling a raw query and running it:

const query = `INSERT INTO classes_courses (class_id, course_id) VALUES ${classIds
  .map(classId =>
    courseIds.map(courseId => `('${classId}', '${courseId}')`),
  )
  .join(',')};`;

I don't lose many of the benefits of an ORM that way because an INSERT INTO query is pretty standard accross every major database management system out in the market, but its not very elegant and there should be a way to do this using a query builder or a repository, which would be preferable.

My question is: how would I do it? And if anyone could point me to where they talk about this in the docs it'd be much appreciated.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source