Slick for推导式中如何定义条件执行的空查询?
问题原因
你遇到的编译错误是因为if表达式的两个分支返回类型不匹配:
- 条件成立的分支返回的是
slick.jdbc.JdbcActionComponent#ProfileAction类型(SQL执行动作) - 条件不成立的分支返回的是
Query.empty(查询定义对象,不是可执行的Action)
两者的公共父类是Object,不具备for推导要求的flatMap方法,因此编译失败。
正确实现方案
你只需要将条件不成立的分支替换为什么都不做的空DBIO动作,保证两个分支类型统一即可,推荐使用DBIO.successful(())作为空操作占位:
val queries = for { _ <- if (condition1) query1 else DBIO.successful(()) _ <- if (condition2) query2 else DBIO.successful(()) id <- someInsertQuery } yield id db.run(queries.transactionally)
DBIO.successful(())会直接返回成功状态的Unit类型结果,不会执行任何SQL,完全兼容现有事务逻辑。
Option场景优化
针对你补充的Option判断场景,不需要调用Query.empty.result,直接用对应返回值的空DBIO即可,写法更简洁:
val queries = for { // SomeTableQuery += someRow 返回受影响行数(Int类型),因此空分支返回DBIO.successful(0)对齐类型 _ <- someOption.map(someRow => SomeTableQuery += someRow).getOrElse(DBIO.successful(0)) // 后续其他Action操作 id <- someInsertQuery } yield id
如果不需要用到受影响行数,也可以统一用DBIO.successful(())作为空分支,不影响后续逻辑。
内容的提问来源于stack exchange,提问作者eftshift0
相关产品推荐
相关产品推荐

