nestjs - 是否可以在 TypeORM 的 leftJoinAndSelect 中使用子查询
问题描述
所以我有一个关于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;
}
用户订阅实体
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
...
}
解决方案
使用该SubQueryFactory
选项不会自动将on
子句创建为条件,因为它无法知道您尝试加入的基础查询的别名是什么。.leftJoinAndSelect('user.photos', 'photos')
由于它的编写方式,它没有元数据提供的上下文。
相反,您必须明确定义条件。在你的情况下:
const result = await userRepo
.createQueryBuilder('user')
.leftJoinAndSelect(
qb => qb
.select()
.from(UserPhotos, 'p')
.orderBy({ 'p.updatedAt': 'ASC' })
.limit(5),
'photos',
'photos.userId = user.id' // the answer
)
.getRawMany() // .getMany() seems not working
这是实际答案: https ://github.com/typeorm/typeorm/issues/6767
更新
我看到.getMany()
使用SubQueryFactory
. 您可以使用.getRawMany()
.
推荐阅读
- swiftui - 无法将带有页眉/页脚的部分添加到 SwiftUI 中的列表
- typescript - Typescript - 'any[]' 类型的参数不可分配给'[any?, ...any[]]' 类型的参数
- html - Rails 6:使 number_to_phone 可点击
- xaml - 我的工具栏项目图标未在 Xamarin Ios 中显示
- ios - Native UI Component throws Invariant Violation: 试图注册两个同名的视图 FridgeCameraView
- linux - 为什么dirtyCOW PoC 不能在我的VM 上运行?
- markdown - 在两端对齐的段落中使用 Markdown 语法
- python - 如何清除表格小部件pyqt5以添加新内容
- postgresql - Go SQLBoiler:查询关系并返回
- c++ - 如何使用 C/C++ 获取 bmp 的颜色?