在联结表中键入ORM软删除链接

问题描述 投票:0回答:1

我对 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 nestjs-typeorm
1个回答
0
投票

我已经研究同一问题很长一段时间了,我认为没有直接的解决方案。 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' },
  },
});
© www.soinside.com 2019 - 2024. All rights reserved.