英文:
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:
@Entity()
export class Candidate {
@PrimaryGeneratedColumn()
id: number;
...
@ManyToMany(() => Language, { nullable: true })
@JoinTable()
languages: Language[];
@ManyToMany(() => Tool, { nullable: true })
@JoinTable()
tools: Tool[];
@ManyToMany(() => ActivityArea, { nullable: true })
@JoinTable()
activity_areas: ActivityArea[];
...
@Column({ nullable: true })
desired_starting_date: string;
...
}
Language entity (the others are similar):
@Entity()
export class Language {
@PrimaryGeneratedColumn()
id: number;
@Column({unique: true})
name: string;
}
I tried to use the update function of typeORM:
async update(id: number, updateCandidateDto: UpdateCandidateDto) {
try {
const candidate = this.generateaCandidate(updateCandidateDto); // this is the new value of candidate
return await this.candidateRepository.update({
id
}, {
languages: candidate.languages,
tools: candidate.tools,
activity_areas: candidate.activity_areas,
desired_starting_date: candidate.desired_starting_date
});
} catch (error) {
throw new HttpException(error.detail, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
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:
@Entity()
export class Candidate {
@PrimaryGeneratedColumn()
id: number;
...
@ManyToMany(() => Language, { nullable: true })
@JoinTable()
languages: Language[];
@ManyToMany(() => Tool, { nullable: true })
@JoinTable()
tools: Tool[];
@ManyToMany(() => ActivityArea, { nullable: true })
@JoinTable()
activity_areas: ActivityArea[];
...
@Column({ nullable: true })
desired_starting_date: string;
...
}
Language entity (the others are similar):
@Entity()
export class Language {
@PrimaryGeneratedColumn()
id: number;
@Column({unique: true})
name: string;
}
I tried to use the update function of typeORM :
async update(id: number, updateCandidateDto: UpdateCandidateDto) {
try {
const candidate = this.generateaCandidate(updateCandidateDto); // this is the new value of candidate
return await this.candidateRepository.update({
id
}, {
languages: candidate.languages,
tools: candidate.tools,
activity_areas: candidate.activity_areas,
desired_starting_date: candidate.desired_starting_date
});
} catch (error) {
throw new HttpException(error.detail, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
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
我终于找到了一种方法来做到这一点:
async update(id: number, updateCandidateDto: UpdateCandidateDto) {
try {
const new_candidate = await this.generateCandidate(updateCandidateDto);
for (const prop in new_candidate) {
if (typeof new_candidate[prop] == 'object') {
const actualRelationships = await this.candidateRepository
.createQueryBuilder()
.relation(Candidate, prop)
.of(id)
.loadMany();
await this.candidateRepository
.createQueryBuilder()
.relation(Candidate, prop)
.of(id)
.addAndRemove(new_candidate[prop], actualRelationships);
} else {
const json = JSON.parse(`{ "${prop}" : "${new_candidate[prop]}" }`);
this.candidateRepository
.createQueryBuilder()
.update(Candidate)
.set(json)
.where('id = :id', {id: id})
.execute();
}
}
return await this.findOne(id);
} catch (error) {
console.error(error);
throw new HttpException('Update failed', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
我测试要修改的候选人的每个属性,如果属性的类型是'object',那么它意味着它是一个外键。在这种情况下,我从数据库中检索所有相关关系,并用新的关系替换它们。
这个解决方案有效,我会使用它,直到有更好的解决方案被提出。
英文:
I finaly found a way to did it :
async update(id: number, updateCandidateDto: UpdateCandidateDto) {
try {
const new_candidate = await this.generateCandidate(updateCandidateDto);
for (const prop in new_candidate) {
if (typeof new_candidate[prop] == 'object') {
const actualRelationships = await this.candidateRepository
.createQueryBuilder()
.relation(Candidate, prop)
.of(id)
.loadMany();
await this.candidateRepository
.createQueryBuilder()
.relation(Candidate, prop)
.of(id)
.addAndRemove(new_candidate[prop], actualRelationships);
} else {
const json = JSON.parse(`{ "${prop}" : "${new_candidate[prop]}" }`);
this.candidateRepository
.createQueryBuilder()
.update(Candidate)
.set(json)
.where('id = :id', {id: id})
.execute();
}
}
return await this.findOne(id);
} catch (error) {
console.error(error);
throw new HttpException('Update failed', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论