在io.getquill中折叠OR子句列表遇Ast解析错误求助
问题解决:Quill中动态构建OR过滤条件的正确方式
错误原因
你遇到的Tree cannot be parsed to 'Ast'错误,核心原因是Quill的quote宏依赖编译时确定的AST结构,而你用pncnPairs.foldLeft这种运行时集合操作来动态拼接OR条件,宏无法解析这种运行时逻辑生成对应的SQL抽象语法树(AST)。
正确解决方案
Quill提供了liftQuery工具专门处理运行时集合,通过它可以将你的pncnPairs集合转换为可被宏解析的条件,生成对应的SQL OR链或IN子句(取决于数据库适配)。
代码示例
假设你的PNCNPair是如下定义的case class:
case class PNCNPair(patientNumber: String, caseNumber: String)
修改后的过滤条件构建代码:
// 从文件加载的运行时数据集合 val pncnPairs: Seq[PNCNPair] = loadFromYourFile() // 替换为你的文件加载逻辑 // 正确构建过滤条件 val filterCondition = quote { (pr: PatientRegistration.PatientRegistration, cn: CaseRegistration.CaseRegistration) => liftQuery(pncnPairs).exists(pair => pr.PatientNumber == pair.patientNumber && cn.CaseNumber == pair.caseNumber ) } // 在查询中使用该条件 val finalQuery = quote { query[PatientRegistration] .join(query[CaseRegistration]) .on((pr, cn) => /* 这里填写你的表连接条件 */) .filter((pr, cn) => filterCondition(pr, cn)) }
补充说明
- 空集合处理:如果
pncnPairs为空,exists会返回false,导致没有数据被查询。若需要空集合时返回所有数据,可调整条件:val filterCondition = quote { (pr: PatientRegistration.PatientRegistration, cn: CaseRegistration.CaseRegistration) => liftQuery(pncnPairs).isEmpty || liftQuery(pncnPairs).exists(pair => pr.PatientNumber == pair.patientNumber && cn.CaseNumber == pair.caseNumber ) } - SQL生成逻辑:Quill会根据数据库类型自动优化生成的SQL,比如对于PostgreSQL可能生成
EXISTS子查询,对于MySQL可能生成多个OR拼接的条件,无需手动处理底层SQL语法。
内容的提问来源于stack exchange,提问作者DetriusXii
相关产品推荐
相关产品推荐

