Prisma嵌套属性排序报错:如何按角色名称字母序排序用户?
按用户角色名称排序Prisma查询的问题与解决
我用Prisma和TypeScript开发,需要按用户的角色名称字母序对用户列表排序,但执行findMany时控制台报错:
Argument user_roles: Got invalid value 'asc' on prisma.findManymme_user. Provided String, expected mme_user_roleOrderByRelationAggregateInput: type mme_user_roleOrderByRelationAggregateInput { _count?: SortOrder }
试过用_count排序,但需求是按角色名称字母序排序,下面是我的实现代码和Prisma Schema:
实现代码
export async function getUser({ skip, limit, pageSize, search, sortBy }: { skip: number, limit: number, pageSize: number, search: string, sortBy: { id: string, desc: boolean }[] }): Promise<any> { const sorting: { [key: string]: string }[] = sortBy.length > 0 ? sortBy.map((sort: any) => { if (sort.id.includes('.')){ const idArr = sort.id.split('.') let nestedSort: any = { [idArr[idArr.length-1]]: sort.desc ? 'desc' : 'asc' } idArr.reverse().forEach((id: string, index: number) => { if(index > 0){ nestedSort = { [id]: nestedSort } } }) return nestedSort } return { [sort.id]: sort.desc ? 'desc' : 'asc' } }) : [{ userid: 'asc' }] console.log('sorting', JSON.stringify(sorting, null, 2)); console.log('sortby', JSON.stringify(sortBy, null, 2)); const filter = [ { userid: { contains: search }, }, { nama: { contains: search }, }, { role: { contains: search }, }, { email: { contains: search }, }, ] return prisma.mme_user.findMany({ skip, take: Number(pageSize) < Number(limit) ? Number(pageSize) : Number(limit), include: { user_roles: { include: { role: true } } }, where: { is_deleted: 0, OR: filter }, orderBy: sorting }) }
Prisma Schema
model mme_role { id Int @id @default(autoincrement()) name String @unique @db.VarChar(255) privileges mme_privilege[] user_roles mme_user_role[] } model mme_user_role { id Int @id @default(autoincrement()) user_id Int user mme_user @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: Cascade) role_id Int role mme_role @relation(fields: [role_id], references: [id], onDelete: Cascade, onUpdate: Cascade) } model mme_user { id Int @id @default(autoincrement()) userid String @unique(map: "idxUser") @db.VarChar(25) passwd String @db.VarChar(250) nama String @db.VarChar(50) role String @db.VarChar(15) email String @db.VarChar(250) created_at DateTime @db.DateTime(0) last_updated DateTime @db.DateTime(0) is_deleted Int @default(0) @db.UnsignedTinyInt deleted_at DateTime? @db.DateTime(0) logged_in Int @default(0) @db.UnsignedTinyInt activities mme_activity[] notifications mme_notification[] product_price_list mme_product_price_list[] user_roles mme_user_role[] @@index([is_deleted], map: "mme_user_is_deleted") }
问题原因
报错是因为直接对多对多关联字段user_roles用asc/desc排序不合法,Prisma只允许对关联字段用_count统计排序。要按角色名称排序,必须通过关联的role模型的name字段来实现,同时要注意:一个用户可能关联多个角色,需明确排序逻辑。
解决方法
方式1:按用户关联的第一个角色名称排序
修改排序逻辑,针对user_roles.role.name字段生成正确的排序配置:
const sorting: { [key: string]: any }[] = sortBy.length > 0 ? sortBy.map((sort: any) => { // 专门处理角色名称排序的情况 if (sort.id === 'user_roles.role.name') { return { user_roles: { role: { name: sort.desc ? 'desc' : 'asc' } } } } // 其他字段的原有逻辑保持不变 if (sort.id.includes('.')){ const idArr = sort.id.split('.') let nestedSort: any = { [idArr[idArr.length-1]]: sort.desc ? 'desc' : 'asc' } idArr.reverse().forEach((id: string, index: number) => { if(index > 0){ nestedSort = { [id]: nestedSort } } }) return nestedSort } return { [sort.id]: sort.desc ? 'desc' : 'asc' } }) : [{ userid: 'asc' }]
方式2:按用户关联角色名称的极值排序(多角色场景)
如果用户有多个角色,可按角色名称的最小/最大值排序,确保排序逻辑明确:
// 示例:按用户关联角色名称的最小值升序排序 return prisma.mme_user.findMany({ skip, take: Number(pageSize) < Number(limit) ? Number(pageSize) : Number(limit), include: { user_roles: { include: { role: true } } }, where: { is_deleted: 0, OR: filter }, orderBy: [ { user_roles: { _min: { role: { name: 'asc' } } } } ] })
注意事项
- 确保前端传递的排序字段标识
sort.id为user_roles.role.name,与后端逻辑匹配 - 多角色场景下,必须明确排序规则,避免结果不符合预期
内容的提问来源于stack exchange,提问作者Aryagara Kristandy
相关产品推荐
相关产品推荐

