【问题标题】:Comparing type mapped values in Slick queries比较 Slick 查询中的类型映射值
【发布时间】:2014-04-12 01:23:54
【问题描述】:

考虑下面的收藏夹表对象,我们要编写一个查询来按其类型(定义如下)查找收藏夹。我们还定义了一个 Typemapper,用于将 FavoriteType 映射到数据库的 String

import scala.slick.driver.PostgresDriver.simple._
//Other imports have been omitted in this question

object Favorites extends Table[Favorite]("favorites") {

  // Convert the favoriteTypes to strings for the database
  implicit val favoriteMapping: TypeMapper[FavorietType] = MappedTypeMapper.base[FavorietType, String](
    favType => FavorietType.values.find(_ == favType).get.mapping,
    mapping => FavorietType.values.find(_.mapping == mapping).get
  )

  def favoriteType = column[FavoriteType]("type")
  //other columns here

这是我想写的查询(但是它不能编译)

  def queryByFavoriteType(ftype : FavoriteType)(implicit s: Session) = {
    for(
      f <- Favorieten if  f.favoriteType === ftype
    ) yield f
  }
}

这里我定义了不同的 FavoriteType 对象(这是在 Favorieten 对象之外)

sealed case class FavorietType(mapping: String) {
  override def toString = mapping.capitalize
}
object FavoriteType {
  object Exam extends FavoriteType("examen")
  object Topic extends FavoriteType("onderwerp")
  object Paper extends FavoriteType("profielwerkstuk")

  val values = Seq(Exam , Topic , Paper )
}

我在这里遇到的问题是查询无法编译: value === is not a member of scala.slick.lifted.Column[models.gebruiker.FavorietType]

似乎 === 不能用于比较用户定义的类型,这是真的吗?有没有其他方法可以做到这一点?

编辑

相关问题:在我的 TypeMapper 没有显式类型之前,它被定义为 implicit val favoriteMapping = MappedTypeMapper.base[FavorietType, String]( ...

当我编写一个查询来比较一个 FavoriteType.Exam(例如)时,例如

  def queryByFavoriteExam()(implicit s: Session) = {
    for(f <- Favorieten if f.favorietType === FavorietType.Exam) yield f
  }

这将导致错误could not find implicit value for evidence parameter of type scala.slick.lifted.TypeMapper[models.gebruiker.FavorietType.Exam.type] 解决方案与下面介绍的相同

【问题讨论】:

  • 你有哪些 scalaquery 导入?你应该有 org.scalaquery.ql.extended..Implicit._
  • 是的,我已经导入了 scala.slick.driver.PostgresDriver.simple._
  • 值得注意的是,当查询上下文中缺少隐式 Session 时,我也会收到错误 value === is not a member of scala.slick.lifted.Column

标签: scala slick


【解决方案1】:

如果对 Slick 有疑问,go check out the unit tests。在阅读了他们关于自定义类型映射的文档,然后查看了他们的单元测试之后,我通过将查询代码更改为:

def queryByFavoriteType(ftype : FavoriteType)(implicit s: Session) = {
  for(f <- Favorites if f.favoriteType === (ftype:FavoriteType)) yield f
}

另外,我导入了 H2Driver 只是为了编译 (import scala.slick.driver.H2Driver.simple._)。我假设您还导入了您的数据库所需的任何驱动程序。

编辑

我的完整代码示例如下:

import scala.slick.driver.PostgresDriver.simple._
import scala.slick.session.Session

sealed case class FavoriteType(mapping: String) {
  override def toString = mapping.capitalize
}

case class Favorite(ft:FavoriteType, foo:String)
object FavoriteType {
  object Exam extends FavoriteType("examen")
  object Topic extends FavoriteType("onderwerp")
  object Paper extends FavoriteType("profielwerkstuk")

  val values = Seq(Exam , Topic , Paper )
}

object Favorites extends Table[Favorite]("favorites") {
  // Convert the favoriteTypes to strings for the database
  implicit val favoriteMapping = MappedTypeMapper.base[FavoriteType, String](
    {favType => FavoriteType.values.find(_ == favType).get.mapping},
    {mapping => FavoriteType.values.find(_.mapping == mapping).get}
  )

  def favoriteType = column[FavoriteType]("type")
  def foo = column[String]("foo")

  def * = favoriteType ~ foo <> (Favorite.apply _, Favorite.unapply _)

  def queryByFavoriteType(ftype : FavoriteType)(implicit s: Session) = {
    for(f <- Favorites if f.favoriteType === (ftype:FavoriteType)) yield f
  }   
}

【讨论】:

  • 我已经导入了 scala.slick.driver.PostgresDriver.simple._ ,我尝试了您建议的解决方案,但这并没有解决我的问题,我仍然收到错误 value === is not a member of scala.slick.lifted.Column[models.gebruiker.FavoriteType]。仅当我使用 === 比较用户定义的类型时才会出现此问题,我可以将 === 用于 Ints 和其他原始值
  • @Fritsie,我发布了我的完整代码示例,切换到你的驱动程序,事情仍然可以编译。我希望所有的代码都对你有用。
  • 原来implicit val favoriteMapping: TypeMapper[FavorietType]是你的第一个代码sn-p不起作用的原因,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
相关资源
最近更新 更多