Выберите одну строку на основе идентификатора в Slick

Я хочу запросить одну строку от пользователя на основе идентификатора. У меня есть следующий фиктивный код

case class User(
    id: Option[Int], 
    name: String
}

object Users extends Table[User]("user") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def * = id ~ name <>(User, User.unapply _)

  def findById(userId: Int)(implicit session: Session): Option[User] = {
    val user = this.map { e => e }.where(u => u.id === userId).take(1)
    val usrList = user.list
    if (usrList.isEmpty) None
    else Some(usrList(0))
  }
}

Мне кажется, что findById является излишним для запроса одного столбца, поскольку Id является стандартным первичным ключом. Кто-нибудь знает лучшие способы? Обратите внимание, что я использую Play! 2.1.0


person Khalid Saifullah    schedule 09.05.2013    source источник
comment
Очень хороший пример: becompany.ch/en /blog/2016/12/15/slick-dos-and-donts   -  person Allenaz    schedule 09.11.2018


Ответы (4)


Используйте метод headOption в Slick 3.*:

  def findById(userId: Int): Future[Option[User]] ={
    db.run(Users.filter(_.id === userId).result.headOption)
  }
person Saeed Zarinfam    schedule 03.09.2016
comment
Есть ли способ сделать что-то похожее на LINQ, где есть метод .First(), а также метод .Single()? .First просто возвращает первую строку, а .Single генерирует исключение, если в результирующем наборе более 1 строки. - person Tadej Mali; 27.10.2017

Вы можете удалить две строки из своей функции, переключившись с list на firstOption. Это будет выглядеть так:

def findById(userId: Int)(implicit session: Session): Option[User] = {
  val user = this.map { e => e }.where(u => u.id === userId).take(1)
  user.firstOption
}

Я полагаю, что вы также сделаете свой запрос следующим образом:

def findById(userId: Int)(implicit session: Session): Option[User] = {
  val query = for{
    u <- Users if u.id === userId
  } yield u
  query.firstOption
}
person cmbaxter    schedule 09.05.2013
comment
Как вы думаете, возможно, firstOption был удален из lifted.Query в Slick 2.1? Я считаю, что это было. slick.typesafe.com/doc/2.1.0 /api/#scala.slick.lifted.Query - person Peter Becich; 17.09.2014
comment
Его больше нет - этот ответ устарел - person BrokenGlass; 07.10.2016

firstOption это путь, да.

Имея

  val users: TableQuery[Users] = TableQuery[Users]

мы можем написать

def get(id: Int): Option[User] = users.filter { _.id === id }.firstOption
person tuxSlayer    schedule 17.05.2014

Более короткий ответ.

  `def findById(userId: Int)(implicit session: Session): Option[User] = {
     User.filter(_.id === userId).firstOption
        }`
person binkabir    schedule 17.02.2015