Сравнение сопоставленных значений типов в запросах Slick

Рассмотрим объект таблицы «Избранное» ниже. Мы хотим написать запрос для поиска «Избранного» по их типу (определенному ниже). Мы также определили Typemapper для сопоставления FavoriteType со строкой для базы данных.

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] Решение для этого такое же, как и представленное ниже.


person Wellingr    schedule 09.08.2013    source источник
comment
Какие у вас есть импортные скалярии? У вас должен быть org.scalaquery.ql.extended.‹YourDBDriver›.Implicit._   -  person Ratan Sebastian    schedule 09.08.2013
comment
Да, я импортировал scala.slick.driver.PostgresDriver.simple._   -  person Wellingr    schedule 09.08.2013
comment
Примечательно, что я также получаю сообщение об ошибке value === is not a member of scala.slick.lifted.Column, когда неявный сеанс отсутствует/отсутствует в контексте запроса.   -  person Jay Taylor    schedule 11.04.2014


Ответы (1)


Если вы сомневаетесь в Slick, ознакомьтесь с модульными тестами. Прочитав их документы по отображению в пользовательском типе, а затем просмотрев их модульные тесты, я получил ваш код запроса для компиляции, изменив его на:

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
  }   
}
person cmbaxter    schedule 09.08.2013
comment
Я импортировал scala.slick.driver.PostgresDriver.simple._ , я попробовал предложенное вами решение, однако это не решило проблему для меня, я все еще получаю сообщение об ошибке value === is not a member of scala.slick.lifted.Column[models.gebruiker.FavoriteType]. Эта проблема возникает только в том случае, если я использую === для сравнения определяемого пользователем типа, я могу использовать === для целых чисел и других примитивных значений. - person Wellingr; 09.08.2013
comment
@Fritsie, я разместил свой полный пример кода, переключившись на ваш драйвер, и все еще компилируется. Я надеюсь, что весь код будет работать для вас. - person cmbaxter; 09.08.2013
comment
Оказывается, implicit val favoriteMapping: TypeMapper[FavorietType] была причиной того, что ваш первый фрагмент кода не работал, спасибо! - person Wellingr; 09.08.2013