如何使用TypeORM更新ManyToMany关系?

huangapple go评论95阅读模式
英文:

How to update a ManyToMany relation with TypeORM?

问题

I have a candidate entity with many "ManyToMany" relations, I need to create an update function for this entity.
Here is my candidate entity:

  1. @Entity()
  2. export class Candidate {
  3. @PrimaryGeneratedColumn()
  4. id: number;
  5. ...
  6. @ManyToMany(() => Language, { nullable: true })
  7. @JoinTable()
  8. languages: Language[];
  9. @ManyToMany(() => Tool, { nullable: true })
  10. @JoinTable()
  11. tools: Tool[];
  12. @ManyToMany(() => ActivityArea, { nullable: true })
  13. @JoinTable()
  14. activity_areas: ActivityArea[];
  15. ...
  16. @Column({ nullable: true })
  17. desired_starting_date: string;
  18. ...
  19. }

Language entity (the others are similar):

  1. @Entity()
  2. export class Language {
  3. @PrimaryGeneratedColumn()
  4. id: number;
  5. @Column({unique: true})
  6. name: string;
  7. }

I tried to use the update function of typeORM:

  1. async update(id: number, updateCandidateDto: UpdateCandidateDto) {
  2. try {
  3. const candidate = this.generateaCandidate(updateCandidateDto); // this is the new value of candidate
  4. return await this.candidateRepository.update({
  5. id
  6. }, {
  7. languages: candidate.languages,
  8. tools: candidate.tools,
  9. activity_areas: candidate.activity_areas,
  10. desired_starting_date: candidate.desired_starting_date
  11. });
  12. } catch (error) {
  13. throw new HttpException(error.detail, HttpStatus.INTERNAL_SERVER_ERROR);
  14. }
  15. }

But I got the following error: Error: Cannot query across many-to-many for property tools

I check the following post before posting this one:
https://stackoverflow.com/questions/54137386/update-a-many-to-many-relationship-with-typeorm
https://stackoverflow.com/questions/73507196/typeorm-nestjs-update-manytomany-relation-when-using-querybuilder-violates-not
https://stackoverflow.com/questions/49596061/typeorm-updating-entity-table

Can you help me to build an update function that allows me to update several ManyToMany parameters?

英文:

I have a candidate entity with many "ManyToMany" relations, I need to create an update function for this entity.
Here is my candidate entity:

  1. @Entity()
  2. export class Candidate {
  3. @PrimaryGeneratedColumn()
  4. id: number;
  5. ...
  6. @ManyToMany(() => Language, { nullable: true })
  7. @JoinTable()
  8. languages: Language[];
  9. @ManyToMany(() => Tool, { nullable: true })
  10. @JoinTable()
  11. tools: Tool[];
  12. @ManyToMany(() => ActivityArea, { nullable: true })
  13. @JoinTable()
  14. activity_areas: ActivityArea[];
  15. ...
  16. @Column({ nullable: true })
  17. desired_starting_date: string;
  18. ...
  19. }

Language entity (the others are similar):

  1. @Entity()
  2. export class Language {
  3. @PrimaryGeneratedColumn()
  4. id: number;
  5. @Column({unique: true})
  6. name: string;
  7. }

I tried to use the update function of typeORM :

  1. async update(id: number, updateCandidateDto: UpdateCandidateDto) {
  2. try {
  3. const candidate = this.generateaCandidate(updateCandidateDto); // this is the new value of candidate
  4. return await this.candidateRepository.update({
  5. id
  6. }, {
  7. languages: candidate.languages,
  8. tools: candidate.tools,
  9. activity_areas: candidate.activity_areas,
  10. desired_starting_date: candidate.desired_starting_date
  11. });
  12. } catch (error) {
  13. throw new HttpException(error.detail, HttpStatus.INTERNAL_SERVER_ERROR);
  14. }
  15. }

But I got the following error : Error: Cannot query across many-to-many for property tools

I check the following post before posting this one:
https://stackoverflow.com/questions/54137386/update-a-many-to-many-relationship-with-typeorm
https://stackoverflow.com/questions/73507196/typeorm-nestjs-update-manytomany-relation-when-using-querybuilder-violates-not
https://stackoverflow.com/questions/49596061/typeorm-updating-entity-table

Can you help me to build an update function that allows me to update several ManyToMany parameters?

答案1

得分: 0

我终于找到了一种方法来做到这一点:

  1. async update(id: number, updateCandidateDto: UpdateCandidateDto) {
  2. try {
  3. const new_candidate = await this.generateCandidate(updateCandidateDto);
  4. for (const prop in new_candidate) {
  5. if (typeof new_candidate[prop] == 'object') {
  6. const actualRelationships = await this.candidateRepository
  7. .createQueryBuilder()
  8. .relation(Candidate, prop)
  9. .of(id)
  10. .loadMany();
  11. await this.candidateRepository
  12. .createQueryBuilder()
  13. .relation(Candidate, prop)
  14. .of(id)
  15. .addAndRemove(new_candidate[prop], actualRelationships);
  16. } else {
  17. const json = JSON.parse(`{ "${prop}" : "${new_candidate[prop]}" }`);
  18. this.candidateRepository
  19. .createQueryBuilder()
  20. .update(Candidate)
  21. .set(json)
  22. .where('id = :id', {id: id})
  23. .execute();
  24. }
  25. }
  26. return await this.findOne(id);
  27. } catch (error) {
  28. console.error(error);
  29. throw new HttpException('Update failed', HttpStatus.INTERNAL_SERVER_ERROR);
  30. }
  31. }

我测试要修改的候选人的每个属性,如果属性的类型是'object',那么它意味着它是一个外键。在这种情况下,我从数据库中检索所有相关关系,并用新的关系替换它们。

这个解决方案有效,我会使用它,直到有更好的解决方案被提出。

英文:

I finaly found a way to did it :

  1. async update(id: number, updateCandidateDto: UpdateCandidateDto) {
  2. try {
  3. const new_candidate = await this.generateCandidate(updateCandidateDto);
  4. for (const prop in new_candidate) {
  5. if (typeof new_candidate[prop] == 'object') {
  6. const actualRelationships = await this.candidateRepository
  7. .createQueryBuilder()
  8. .relation(Candidate, prop)
  9. .of(id)
  10. .loadMany();
  11. await this.candidateRepository
  12. .createQueryBuilder()
  13. .relation(Candidate, prop)
  14. .of(id)
  15. .addAndRemove(new_candidate[prop], actualRelationships);
  16. } else {
  17. const json = JSON.parse(`{ "${prop}" : "${new_candidate[prop]}" }`);
  18. this.candidateRepository
  19. .createQueryBuilder()
  20. .update(Candidate)
  21. .set(json)
  22. .where('id = :id', {id: id})
  23. .execute();
  24. }
  25. }
  26. return await this.findOne(id);
  27. } catch (error) {
  28. console.error(error);
  29. throw new HttpException('Update failed', HttpStatus.INTERNAL_SERVER_ERROR);
  30. }
  31. }

I test each property of the candidate I want to modify, if the property is of type 'object' it means that it is a foreign key. In this case, I retrieve all its relations from the database and replace them with the new relations.

This solution works, I will use it until a better solution is proposed.

huangapple
  • 本文由 发表于 2023年3月15日 20:30:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75744712.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定