在Slick中使用自定义列类型时进行过滤

时间:2015-05-27 13:23:35

标签: scala slick slick-2.0

在使用自定义列类型时,我在Slick 2.1.0中查询/过滤时遇到了一些困难。 我的问题的简化版本:

import scala.slick.driver.MySQLDriver.simple._

sealed class Status(val intValue: Int)
case object Active extends Status(1)
case object Disabled extends Status(2)
case object Deleted extends Status(3)

case class TableMapping(id: Long, status: Status)

class MyTableDefinition(tag: Tag) extends Table[TableMapping](tag, "sometable") {
  implicit val statusColumnType = MappedColumnType.base[Status, Int](statusToInt, intToStatus)

  def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
  def status = column[Status]("STATUS", O.NotNull, O.Default(Active))
  def * = (id, status) <> (TableMapping.tupled, TableMapping.unapply)

  private def statusToInt(s: Status): Int = s.intValue
  private def intToStatus(i: Int): Status = i match {
    case 1 => Active
    case 2 => Disabled
    case _ => Deleted
  }
}

class MyTableDao {
    val Items = TableQuery[MyTableDefinition]
    def byId(id: Long)(implicit session: Session): Option[TableMapping] = {
      Items.filter(_.status =!= Deleted).firstOption
    }
}

我收到了一个编译错误:

Items.filter(_.status =!= Deleted).firstOption

错误说明:

value =!= is not a member of scala.slick.lifted.Column[Status]
[error] def byId(id: Long)(implicit session: Session): Option[TableMapping] =
  Items.filter(_.status =!= Deleted).firstOption

我做错了什么想法?也许还有更好的方法可以做到这一点,我不知道?

2 个答案:

答案 0 :(得分:8)

问题是Scala编译器将寻找Deleted.type而不是Status的隐式转换。

由于Deleted被声明为object,它不是一个类,它的实际类是Deleted.type,所以你只需要帮助编译器理解它实际上是Status 1}}。怎么样?你可以尝试

class MyTableDao {
val Items = TableQuery[MyTableDefinition]

def byId(id: Long)(implicit session: Session): Option[TableMapping] =
    Items.filter(_.status =!= Deleted.asInstanceOf[Status]).firstOption
}

那样做。

让我知道如果它确实有效,我面临类似的问题,我能够摆脱它。

答案 1 :(得分:0)

您的自定义类型映射器需要在DAO的范围内;我做了类似的事情:

trait MyTypeMapper {
  protected implicit val statusColumnType = 
    MappedColumnType.base[Status, Int](_.intValue, intToStatus)

  private def intToStatus(i: Int): Status = i match {
    case 1 => Active
    case 2 => Disabled
    case _ => Deleted
  }
}

然后将特征混合到表映射器和dao:

class MyTableDefinition(tag: Tag) 
  extends Table[TableMapping](tag, "sometable")
  with MyTypeMapper {...}

class MyTableDao extends MyTypeMapper{...}