我对 TypeORM 很陌生,并尝试在联结表(或“链接表”)的帮助下使用多对多关系。
我在数据库中使用软删除 - 甚至在连接表中的关系链接上也是如此。
使用 queryBuilder 构建查询时,如果链接被软删除,我想排除相关实体。
我在文档中找不到任何内容,也没有在 Stackoverflow 上找到任何与此相关的问题。所以我开始想知道是否有可能,甚至是一个如此糟糕的想法以至于没有人考虑软删除链接? :-D
我的表格的简化示例如下所示:
UsersTable
*--------*-------------------------------*
| Id | Name |
*--------*-------------------------------*
| 1 | Bruce Lee |
| 2 | Brad Pitt |
*--------*-------------------------------*
GroupsTable
*--------*-------------------------------*
| Id | Name |
*--------*-------------------------------*
| 1 | Actors |
| 2 | Aliens |
*--------*-------------------------------*
JunctionTable
*--------*---------*---------------------*
| UserId | GroupId | DeletedAt |
*--------*---------*---------------------*
| 1 | 1 | |
| 2 | 1 | |
| 2 | 2 | 2023-12-08 01:02:03 | <-- Brad Pitt is soft deleted
*--------*---------*---------------------* from Aliens
我的实体看起来像这样:
@Entity('JuctionTable')
export class Jucation {
@PrimaryColumn()
UserId: number;
@PrimaryColumn()
GroupId: number;
@DeleteDateColumn() // Soft deleting column
DeletedAt: Date;
}
@Entity('UsersTable')
export class UserEntity {
@PrimaryColumn()
Id: number;
@Column()
Name: string;
@ManyToMany(() => GroupEntity, (group) => group.Users)
@JoinTable({
name: 'JuctionTable',
joinColumn: { referencedColumnName: 'Id', name: 'UserId' },
inverseJoinColumn: { referencedColumnName: 'Id', name: 'GroupId' },
})
Groups: GroupEntity[];
}
@Entity('GroupsTable')
export class GroupEntity {
@PrimaryColumn()
Id: number;
@Column()
Name: string;
@ManyToMany(() => UserEntity, (user) => user.Groups)
@JoinTable({
name: 'JuctionTable',
joinColumn: { referencedColumnName: 'Id', name: 'GroupId' },
inverseJoinColumn: { referencedColumnName: 'Id', name: 'UserId' },
})
Users: UserEntity[];
}
我的查询如下所示:
const users = await myRepository.createQueryBuilder('User')
.innerJoinAndSelect('User.Groups', 'Groups')
.getMany();
数据返回如下所示:
[
{
Id: 1,
Name: 'Bruce Lee',
Groups: [
{ Id: 1, Name: 'Actors' }
]
},
{
Id: 2,
Name: 'Brad Pitt',
Groups: [
{ Id: 1, Name: 'Actors' },
{ Id: 2, Name: 'Aliens' } <-- I don't want this group,
] the link is soft deleted
}
]
由于链接被软删除,我希望 TypeORM 不会在结果集中包含 Aliens 组。
我已经研究同一问题很长一段时间了,我认为没有直接的解决方案。 TypeORM 期望联结表只有外键。所以生成的SQL没有
AND junction_table.deletedAt IS NULL
。
参考:Github Issue,类似stackoverflow question
尽管很难看,但唯一可行的方法是使用自定义属性实现多对多,就像在 docs 中指定的那样。
因此,对于您的问题,您将这样查询:
const users = await UserEntity.find({
where: {
userGroups: { groupId: 'group.id' },
// or
// userGroups: { groups: { name: 'group_name' } },
// but this won't work:
// groups: { name: 'group_name' },
},
});