UPDATE 2
实际上一个不需要concat,因为它也可以写成如下:
filter(s => LiteralColumn(prefix) like (s.prefix ++ "%"))
UPDATE:
在cvogt提示后,这是不使用内部Slick API的最终结果:
val concat = SimpleBinaryOperator[String]("||")
Rates.filter(_.ratePlanId === ratePlan)
.filter(_.present === true)
.filter(s => LiteralColumn(prefix) like concat(s.prefix, "%"))
.sortBy(_.prefix.desc).firstOption
完美地给出了:
and ('3113212512' like (x2."prefix" || '%'))
Alternative:
这似乎是可能的 . 但请注意,以下方法使用Slick的内部API,并且由于API更改,将来可能不兼容(请参阅cvogt的评论)我使用了Slick 2.1.0 .
基本上我创建了一个Slick的扩展,我在其中定义了一个自定义方案来实现所需的结果:
package utils
import scala.language.{higherKinds, implicitConversions}
import scala.slick.ast.ScalaBaseType._
import scala.slick.ast._
import scala.slick.lifted.{Column, ExtensionMethods}
object Helpers {
implicit class PrefixExtensionMethods[P1](val c: scala.slick.lifted.Column[P1]) extends AnyVal with ExtensionMethods[String, P1] {
def subPrefixFor[P2, R](prefix: Column[P2])(implicit om: o#arg[String, P2]#to[Boolean, R]) = {
om.column(Library.Like, prefix.toNode, om.column(new Library.SqlOperator("||"), n, LiteralNode("%")).toNode)
}
}
}
现在可以按如下方式使用:
import utils.Helpers._
[...]
def findActiveRateByRatePlanAndPartialPrefix(ratePlan: String, prefix: String) = {
DB withSession {
implicit session: Session =>
Rates.filter(_.ratePlanId === ratePlan)
.filter(_.present === true)
.filter(_.prefix subPrefixFor prefix)
.sortBy(_.prefix.desc).firstOption
}
}
并将呈现正确的结果:
and ('3113212512' like (x2."prefix" || '%'))
笔记:
我可能有更好的命名
必须链接||和使用om.column一样
我引入了新的SqlOperator,因为Or运算符渲染或者我需要在Postgres中连接||