【发布时间】:2021-11-20 09:27:07
【问题描述】:
所以我有一个关于nestjs 并使用TypeORM 的项目。我的情况是我有一个与 UserSubscrtion 有一对一关系的用户。默认查找查询将所有订阅添加到用户,因为它应该是。所以现在我想找到一个特定的订阅,例如最后添加的。所以我建立了这个查询:
const query = this.createQueryBuilder("user")
.leftJoinAndSelect("user.settings", "settings")
.leftJoinAndSelect(
subQuery => {
return subQuery
.select()
.from(UserSubscription, "subscription")
.where("subscription.userId = :id AND subscription.isConfirmed = :isConfirmed", { id, isConfirmed: true })
.orderBy('"createdDate"', 'DESC')
.limit(1);
}, 'subscription', '"subscription"."userId" = "user"."id"')
.where('user.id = :id', { id });
const result = await query.getOne(); // await query.execute()
首先,我尝试执行查询,它工作正常,但所有数据都不是结构化的
[
{
user_id: 1,
user_username: 'name',
...
settings_id: 1,
settings_ifOnline: true,
...
subscriptions_id: 1,
subscriptions_subscriptionId: 1,
...
}
]
所以不好。
然后我尝试 query.getOne() 但它无法按我的意愿工作,它丢失了所有订阅数据
User {
id: 1,
username: 'name',
...
settings: UserNotificationSettings {
id: 1,
ifOnline: true,
...
}
}
另外,我尝试将虚拟字段订阅添加到用户实体并尝试使用 leftJoinAndMapOne:
...
.leftJoinAndSelect("user.settings", "settings")
.leftJoinAndMapOne("user.subscription",
subQuery => {
return subQuery
.select()
.from(UserSubscription, "subscription")
.where("subscription.userId = :id AND subscription.isConfirmed = :isConfirmed", { id, isConfirmed: true })
.orderBy('"createdDate"', 'DESC')
.limit(1);
}, 'subscription', '"subscription"."userId" = "user"."id"')
...
但没有运气。在文档中,据说“FROM、WHERE 和 JOIN 表达式支持子查询”。但没有提供示例。所以,我不知道如何处理这个我相信使用 TypeORM 的查询非常简单。有什么建议么?我有点坚持这个。可能有比 buildibg 查询更好的方法吗?谢谢。
用户.实体
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
...
// subscription: UserSubscription;
@OneToMany(type => UserSubscription, subscriptions => subscriptions.user, { cascade:true })
subscriptions: UserSubscription[];
@OneToOne(type => UserNotificationSettings, settings => settings.user, { cascade:true })
settings: UserNotificationSettings;
}
UserSubscription.entity
export class UserSubscription extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@OneToOne(type => Subscription)
@JoinColumn()
subscription: Subscription
@Column()
subscriptionId: number
@ManyToOne(type => User, user => user.subscriptions)
user: User
@Column({type: 'integer'})
userId: number
@Column({ type: 'boolean', default: false })
isConfirmed: boolean
...
}
【问题讨论】:
-
你解决了吗?
-
有什么解决办法吗?