Slick select 使用值对象(扩展 AnyVal)

Slick select using value object (extending AnyVal)

我正在使用 Slick 2.1.0 和 Scala 2.10。 我有一个映射到 VARCHAR 列的值对象 (EMail)。

object EMail {
  import java.util.regex.Pattern
  val emailRegex = Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE)

  val empty = EMail("x@y.com")
}

case class EMail(value: String) extends AnyVal with MappedTo[String] {
  def isValid: Boolean = EMail.emailRegex.matcher(value).find

  def validate: EMail = {
    assert(isValid)
    EMail(value.trim.toLowerCase)
  }

  override def toString = validate.value
}

Column定义为:

def email = column[Option[EMail]]("email_address")

这是我编写查找器的尝试:

def findByEmail(email: Option[EMail]): Option[User] =
  database.withSession { implicit session: Session =>
    queryAll.filter(e => e.email.isDefined && e.email === email).firstOption
  }

这是我收到的错误消息:

[error] Users.scala:52: ambiguous implicit values: [error] both value BooleanCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[Boolean] [error] and value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[scala.slick.lifted.Column[Option[Boolean]]] [error] match expected type scala.slick.lifted.CanBeQueryCondition[Nothing] [error] queryAll.filter(_.email === email.map(_.value)).firstOption [error] ^

您不必将 Option[EMail] 传递给您的方法,您可以简单地进行:

def findByEmail(email: EMail): Option[User] = {
  database.withSession { implicit session =>
    queryAll.filter(_.email === email).firstOption
  }
}

如果您确实需要一个 Option[EMail]] 作为输入参数,您应该尝试以下操作:

def findByEmail(emailOpt: Option[EMail]): Option[User] = {
  emailOpt.flatMap { email =>
    database.withSession { implicit session =>
      queryAll.filter(_.email === email).firstOption
    }
  }
}