在NestJS中,当通过ID搜索实体时,如何只返回OneToMany关系的选择组?

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

我正在使用 NestJS 10 和 TypeORM 0.3.17。我有这个实体...

@Entity()
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @OneToMany(() => Contact, (contact) => contact.owner, {
    cascade: true,
    onDelete: 'CASCADE',
  })
  contacts?: Contact[];
    ...
}

其中联系人实体有一个字段“isPrimary”...

@Entity()
export class Contact {
  @PrimaryGeneratedColumn('uuid')
  id: string;

    ...
  @Column({ default: false })
  isPrimary: boolean;

我想编写一个方法,该方法将通过 ID 及其相关联系人返回用户实体,但前提是 Contact 对象,但只有那些“isPrimary”等于 true 的相关联系人对象。到目前为止我有这个

@Injectable()
export class UsersService {
  constructor(
    private readonly userRepository: UserRepository,
    ...
  ) {}

    ...
  async findById(id: string): Promise<User> {
    return this.userRepository.findOne({
      select: ['email', 'id', 'refreshToken', 'isEmailConfirmed'],
      relations: ['contacts', 'contacts.mailingAddress', 'contacts.mailingAddress.region'],
      where: { id: id },
    });
  }

但是当前返回与用户关联的所有联系人对象,我只希望返回“isPrimary”为 true 的对象。

nestjs typeorm one-to-many relation
1个回答
0
投票

您需要修改

findById
方法以根据
isPrimary
属性过滤联系人。这可以使用 TypeORM 提供的 查询生成器 来完成。
另请参阅 Eze Sunday 中的“在 NestJS 中使用 TypeORM 的 QueryBuilder”作为示例/教程。

在您的情况下,在查询执行期间使用数据库级过滤:

async findById(id: string): Promise<User | undefined> {
  return this.userRepository.findOne({
    select: ['email', 'id', 'refreshToken', 'isEmailConfirmed'],
    relations: ['contacts', 'contacts.mailingAddress', 'contacts.mailingAddress.region'],
    where: { 
      id: id,
      contacts: {
        isPrimary: true,
      },
    },
    join: {
      alias: 'user',
      leftJoinAndSelect: {
        contacts: 'user.contacts',
      },
    },
  });
}

它使用查询生成器来加入

contacts
关系,并应用条件来仅选择
isPrimary
为 true 的联系人。


更简单的方法是在数据检索后进行内存中过滤:

@Injectable()
export class UsersService {
  constructor(
    private readonly userRepository: UserRepository,
  ) {}

  async findById(id: string): Promise<User> {
    const user = await this.userRepository.findOne({
      select: ['email', 'id', 'refreshToken', 'isEmailConfirmed'],
      relations: ['contacts', 'contacts.mailingAddress', 'contacts.mailingAddress.region'],
      where: { id },
    });

    if (user && user.contacts) {
      user.contacts = user.contacts.filter(contact => contact.isPrimary);
    }
    return user;
  }
}

但是如果用户有大量联系人,则需要获取所有联系人然后进行过滤:效率较低。

© www.soinside.com 2019 - 2024. All rights reserved.