我正在使用 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 的对象。
您需要修改
findById
方法以根据 isPrimary
属性过滤联系人。这可以使用 TypeORM 提供的 查询生成器 来完成。在您的情况下,在查询执行期间使用数据库级过滤:
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;
}
}
但是如果用户有大量联系人,则需要获取所有联系人然后进行过滤:效率较低。