2013-05-09 60 views
8

我想根據ID從用戶查詢單行。我有以下虛設碼根據Slick中的Id選擇單行

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查詢單列作爲標識是標準的主鍵的矯枉過正。有誰知道更好的方法?請注意,我正在使用Play! 2.1.0

回答

7

通過從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 
} 
+1

你認爲firstOption可能從lifted.Query在油滑的2.1被刪除?我相信它已經。 http://slick.typesafe.com/doc/2.1.0/api/#scala.slick.lifted.Query – 2014-09-17 07:30:08

+0

它消失了 - 現在這個答案已經過時了 – BrokenGlass 2016-10-07 18:42:55

4

firstOption是很長的路要走,是的。

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

我們可以寫

def get(id: Int): Option[User] = users.filter { _.id === id }.firstOption 
0

一個較短的答案。

`def findById(userId: Int)(implicit session: Session): Option[User] = { 
    User.filter(_.id === userId).firstOption 
     }` 
0
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.apply _, User.unapply _) 
    // .? in the above line for Option[] 

    val byId = createFinderBy(_.id) 
    def findById(id: Int)(implicit session: Session): Option[User] = user.byId(id).firstOption 
10

使用headOption方法油滑3. *:

def findById(userId: Int): Future[Option[User]] ={ 
    db.run(Users.filter(_.id === userId).result.headOption) 
    } 
+1

有沒有辦法做類似於LINQ的事情?一個.First()方法和一個.Single()方法?首先簡單地返回第一個「行」,如果結果集中有多於一行,則.Single引發異常。 – 2017-10-27 14:27:50