如何在typeORM中保存@ManyToMany中的关系
Posted
技术标签:
【中文标题】如何在typeORM中保存@ManyToMany中的关系【英文标题】:How to save relation in @ManyToMany in typeORM 【发布时间】:2019-07-20 00:31:16 【问题描述】:有 2 个实体名为 Article
和 Classification
。他们的关系是@ManyToMany
。
这是我的问题:如何保存关系?
我的代码如下:
@Entity()
export class Article
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@CreateDateColumn()
createTime: Date;
@UpdateDateColumn()
updateTime: Date;
@Column(
type: 'text',
)
content: string;
@Column(
default: 0,
)
likeAmount: number;
@Column(
default: 0,
)
commentAmount: number;
@Entity()
export class Classification
@PrimaryGeneratedColumn()
id: number;
@CreateDateColumn()
createTime: Date;
@UpdateDateColumn()
updateTime: Date;
@Column()
name: string;
@ManyToMany(type => Article)
@JoinTable()
articles: Article[];
我可以成功保存Article
和Classification
。但我不确定如何保存它们的关系。
我已尝试通过以下代码保存关系:
async create(dto: ArticleClassificationDto): Promise<any>
const article = this.repository.save(dto);
article.then(value =>
console.log(value);//console the object article
value.classification.forEach(item =>
const classification = new Classification();
classification.id = item.id;
classification.articles = [];
classification.articles.push(value);
this.classificationService.save(classification);
)
);
console.log(article);
return null;
还有这样的帖子数据结构
"name":"artile name",
"content":"article content",
"classification":[
"id":4
,
"id":3
]
一开始,它有效。
但是当我再次发布数据时,旧记录被替换而不是创建另一个记录。
接下来我该怎么做?
请看下面的代码。
async create(dto: ArticleClassificationDto): Promise<any>
this.repository.save(dto).then(article =>
article.classification.forEach(item =>
this.ClassificationRepository.findOne(
// the privous method is get all the articles from databse and push into this array
// relations: ['articles'],
where: id: item // now I change the data strcture, just contains id instead of id
).then(classification =>
// console.log(article);
console.log(classification);
// cmd will show ' UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'push' of undefined' withous below line code. But if I init the array manually,the old record will be replaced again.
// classification.articles = [];
classification.articles.push(article);
this.ClassificationRepository.save(classification);
);
)
)
return null;
【问题讨论】:
【参考方案1】:如何保存关系?
假设您有一个文章数组,并且您想要创建与分类实体的关系。您只需将数组分配给属性articles
并保存实体; typeorm 会自动创建关系。
classification.articles = [article1, article2];
await this.classificationRepository.save(classification);
为此,必须已保存文章实体。如果想让typeorm自动保存文章实体,可以将cascade
设置为true
。
@ManyToMany(type => Article, article => article.classifications, cascade: true )
你的例子
async create(dto: ArticleClassificationDto): Promise<any>
let article = await this.repository.create(dto);
article = await this.repository.save(article);
const classifications = await this.classificationRepository.findByIds(article.classification, relations: ['articles']);
for (const classification of classifications)
classification.articles.push(article);
return this.classificationRepository.save(classifications);
【讨论】:
我试过你的方法。它对我不起作用。我已经更新了我的问题,接下来你能帮忙吗? 现在这是一个不同的问题:您将classifications
与他们的id
一起发布。 id
是 classification
实体的 PrimaryGeneratedColumn
。如果要创建新对象,则不能包含主列,否则如果主列 (id
) 已存在,实体将被更新而不是创建。
但我只想保存他们的关系。不保存实体Classification
。我确实想创建一个新对象,但不是classification
,只是classification
和article
的新关系。我需要Classification
的id
自动生成自动- 当我插入一个新的Classification
时增加值。我不清楚如何实现我的目标?
好的,所以所有实体都已经存在;您只想创建实体之间的关系!?然后只需从数据库findOne(classificationId)
加载您的分类实体,将文章分配给您从数据库加载的分类实体,然后保存分类实体。
我已经按照你说的做了。但它有问题。我已经在问题中发布了代码。【参考方案2】:
在我的情况下,我有用户和角色,首先你必须在你的实体中初始化你的多线程:
在用户实体中:
@ManyToMany((type) => Role,
cascade: true,
)
@JoinTable(
name: "users_roles",
joinColumn: name: "userId", referencedColumnName: "id" ,
inverseJoinColumn: name: "roleId"
)
roles: Role[];
在角色实体中:
//Many-to-many relation with user
@ManyToMany((type) => User, (user) => user.roles)
users: User[];
在我的服务中,我从我的数据创建一个新实体,然后我将角色数据添加到我的新实体对象:
let entity = await this.userRepository.create(data);
let entity2 =
...entity,
roles: data.selectedRoles,
;
const user = await this.userRepository.save(entity2);
这是typeorm网站中的例子:
const category1 = new Category();
category1.name = "animals";
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "zoo";
await connection.manager.save(category2);
const question = new Question();
question.title = "dogs";
question.text = "who let the dogs out?";
question.categories = [category1, category2];
await connection.manager.save(question);
【讨论】:
以上是关于如何在typeORM中保存@ManyToMany中的关系的主要内容,如果未能解决你的问题,请参考以下文章
NestJS + TypeORM 中的 JoinTable 问题
使用 TypeORM 在 Postgres bytea 上保存缓冲区仅存储 10 个字节