使用 TypeORM / NestJS 删除多表中的单行
我有一个包含两个实体的 NestJS 项目,一个用户实体和一个聊天室实体,一个聊天室中可以有多个用户,并且用户可以在多个聊天室中,这是聊天室实体:
@Entity()
export class ChatRoom{
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column('int', {array: true, default: []})
public adminId: number[];
@Column()
ownerId: number;
@ManyToMany(() => User, { cascade: true, onUpdate:'CASCADE' })
@JoinTable()
users: User[];
}
和用户实体:
@Entity()
export class User {
@PrimaryColumn()
public id: number;
@Column({nullable: true})
public username: string;
@Column()
public log: string;
@Column({default: 0})
public rank: number;
@Column('int', {array: true, default: []})
public blocked: number[];
@ManyToMany(() => ChatRoom, room => room.users)
rooms: ChatRoom[];
}
对现在使用 querybuilder
我设法获取聊天室中的用户列表并获取用户已加入的聊天室列表,但是我想知道如何删除单个关系(如果用户想要)留下一个房间,如何在不删除用户实体或聊天室实体本身的情况下删除匹配行?
这是我编写的初始聊天室服务代码,以便从聊天室的用户列表中删除特定用户:
async removeUserFromRoom(user: User, roomid: number)
{
const room = await this.chatRepo.findOne(roomid);
if (room)
{
room.users = room.users.filter(user => {
user.id !== user.id
})
await this.chatRepo.save(room);
}
else
throw new HttpException('Room not found', HttpStatus.NOT_FOUND);
}
虽然此解决方案不起作用,因为房间实体没有定义用户数组,但我是否需要按顺序运行查询从聊天室中删除用户?或者有没有办法在 TypeORM 中处理这个问题?如果我似乎误解了某些内容,请告诉我,因为我对数据库和查询相对较新。
I have a nestJS
project with two entities, a user entity and a chatroom entity, there can be multiple users in a chatroom and users can be in multiple chatrooms, here's the chatroom entity :
@Entity()
export class ChatRoom{
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column('int', {array: true, default: []})
public adminId: number[];
@Column()
ownerId: number;
@ManyToMany(() => User, { cascade: true, onUpdate:'CASCADE' })
@JoinTable()
users: User[];
}
and user entity :
@Entity()
export class User {
@PrimaryColumn()
public id: number;
@Column({nullable: true})
public username: string;
@Column()
public log: string;
@Column({default: 0})
public rank: number;
@Column('int', {array: true, default: []})
public blocked: number[];
@ManyToMany(() => ChatRoom, room => room.users)
rooms: ChatRoom[];
}
Right now with querybuilder
I managed to get the list of users in a chatroom and to get the list of chatrooms a user has joined, however I would like to know how to delete a single relationship, if a user wants to leave a room, how do i remove the matching row without removing the user entity or the chatroom entity itself ?
This is the initial chatroom service code I wrote in order to remove a specific user from a chatroom's users list :
async removeUserFromRoom(user: User, roomid: number)
{
const room = await this.chatRepo.findOne(roomid);
if (room)
{
room.users = room.users.filter(user => {
user.id !== user.id
})
await this.chatRepo.save(room);
}
else
throw new HttpException('Room not found', HttpStatus.NOT_FOUND);
}
Although this solution will not work because the room entity does not have an array of users defined, do I need to run a query in order to remove the user from the chatroom ? or is there a way to handle this in TypeORM
? if it seems like I misunderstood something please let me know as I am relatively new to databases and queries.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的
room
实体没有users
数组,因为您在使用存储库时不查询关系。const room = wait this.chatRepo.findOne(roomid, {relations: ['users'] }); 应该解决这个问题。
Your
room
entity does not have ausers
array because you don't query the relation when using the repository.const room = await this.chatRepo.findOne(roomid, { relations: ['users'] });
should fix this.根据文档,似乎只能从“拥有”方进行删除。
根据您的需要,您可以:
当前模型,需要将房间从用户中移除。 (是的,这在语法上是不正确的,但它说明了您必须做什么。)
因此您要搜索房间中的用户,而不是用户的房间。
但是...您有用户,所以:
重要的是
您需要分析用例,因为您可能会发现将
@JoinTable()
移动到User
实体更有效。但是等等...
你搞砸了房间里没有定义的用户。所以:
你已经定义了它们(它们可能已经被卸载。很容易检查,只需使用
console.log(await room.users)
)你的代码中有一个错误:你定义了 < code>user 变量两次。在主函数中,再次在过滤器中。最后,条件
user.id != user.id
始终为true
,因为您比较来自过滤器的用户。顺便说一句:
出于性能原因,由于相关记录的潜在数量,我会将“拥有”一侧移至“用户”。 (通常每个频道的用户数量多于频道预用户数量)
According to the documentation, it seems that deletion is only possible from the 'owning' side.
Depending on your needs, you can:
With the current model, you need to remove the room from the user. (Yes, this is grammatically incorrect, but it illustrates what you have to do.)
So you are to search for the user in the room, not the users' rooms.
But... You have user, so:
Important thing
You need to analyze use cases as you may find it more efficient to move
@JoinTable()
to theUser
entity.But wait ...
You messed up that you have no defined users in the room. So:
you have them defined (they could have been unloaded. It's easy to check, just use
console.log(await room.users)
)you have a bug in your code: you define the
user
variable twice. In the main function and again in the filter. Finally, the conditionuser.id != user.id
is alwaystrue
because you compare the user from the filter.BTW:
For performance reasons, I would move the 'owning' side to 'User' due to the potential amount of related records. (Typically there are more users per channel than channels pre user)