使用 TypeORM 更新多对多关系

Jon*_*han 8 javascript node.js typeorm

我在更新具有多对多关系的实体时遇到问题,想知道我是否做错了什么,或者更具体地说,这样做的正确方法是什么

考虑以下实体...

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

  @Column()
  name: string;

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

  ...

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

  @ManyToMany(() => Subject, (subject: Subject) => subject.notes)
  subjects: Subject[];
Run Code Online (Sandbox Code Playgroud)

在我的代码中,我找到了节点,然后尝试更新它并像这样保存......

const note = await noteRepo.findOneOrFail(noteId);
const foundSubjects = await subjectRepo.findByIds(Array.from(subjectIds));
note.subjects = foundSubjects;
noteRepo.save(note);
Run Code Online (Sandbox Code Playgroud)

但可惜的是,主题没有保存在笔记中。

这样做的正确方法是什么?

谢谢!

Nes*_*rez 9

在我的例子中,我试图更新一个现有的关系,但这给了我一个唯一的键违规,因为关系已经存在,所以我首先需要删除所有现有的关系,然后添加我更新用户的关系:

export const updateUser = async (user: User): Promise<User | undefined> => {
    /**
     * Get the actual relationships of that user.
     */
    const actualRelationships = await getRepository(User)
        .createQueryBuilder()
        .relation(User, 'roles')
        .of(user).loadMany();

    /**
     * Add new relationships of the user, and delete the old relationships.
     */
    await getRepository(User)
        .createQueryBuilder()
        .relation(User, 'roles')
        .of(user)
        .addAndRemove(user.roles, actualRelationships);

    /**
     * Update only the table USER.
     */
    await getRepository(User)
        .createQueryBuilder()
        .update()
        .set({
            name: user.name,
            username: user.username,
            active: user.active
        })
        .where('id = :id', {id: user.id})
        .execute();

    /**
     * Return the updated user
     */
    return await getUser(user.id, true, true)
};
Run Code Online (Sandbox Code Playgroud)

  • 最好将所有这些操作放在一个事务中 (6认同)

Jon*_*han 8

所以以下内容对我有用:

  subjectIds.forEach(async id => {
  await connection
    .createQueryBuilder()
    .relation(Note, 'subjects')
    .of(note)
    .add(id);
});
Run Code Online (Sandbox Code Playgroud)

不过,我仍然觉得 repo.save() 方法应该有效

  • 您不需要“forEach”。`.add` 还接受 Id 数组。应该稍微简化一下代码。 (4认同)

Jud*_*dge 5

默认情况下级联设置为 false,您可以按如下方式启用它:

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

@ManyToMany(() => Subject, (subject: Subject) => subject.notes, { cascade: true })
subjects: Subject[];
Run Code Online (Sandbox Code Playgroud)

  • `note.subjects = [{id:1}, {id:2}]; noteRepo.save(note);` 然后就可以工作了。 (2认同)
  • 这适用于添加新主题,但如果我们想用其他 id 替换这些 id 该怎么办?我们必须使用`.relation().of().addAndRemove()`吗? (2认同)