2013-05-09 13 views
8

Ich möchte eine einzelne Zeile von Benutzer basierend auf ID abfragen. Ich habe folgende BlindkodeWählen Sie eine einzelne Zeile basierend auf ID in 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)) 
    } 
} 

Es scheint mir, dass findById ein Overkill ist eine einzelne Spalte zur Abfrage als Id Standard Primärschlüssel ist. Kennt jemand bessere Wege? Bitte beachten Sie, dass ich Play verwende! 2.1.0

Antwort

7

Sie könnten zwei Zeilen aus Ihrer Funktion entfernen, indem Sie von list zu firstOption wechseln. Das würde wie folgt aussehen:

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

Ich glaube, Sie auch Ihre Abfrage wie folgt tun würde:

def findById(userId: Int)(implicit session: Session): Option[User] = { 
    val query = for{ 
    u <- Users if u.id === userId 
    } yield u 
    query.firstOption 
} 
+1

Glauben Sie firstOption von lifted.Query in Slick 2.1 entfernt wurden? Ich glaube es war. http://slick.typesafe.com/doc/2.1.0/api/#scala.slick.lifted.Query –

+0

Es ist weg - diese Antwort ist jetzt veraltet – BrokenGlass

4

firstOption ein Weg zu gehen, ja.

Mit

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

können wir

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

Eine kürzere Antwort schreiben.

`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

Verwenden headOption Methode in Slick 3. *:

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

Gibt es eine Möglichkeit, etwas Ähnliches wie in LINQ zu tun, wo es gibt eine .First() Methode und auch eine .Single() Methode? .Wird zuerst die erste "Zeile" zurückgegeben und .Single löst eine Ausnahme aus, wenn mehr als 1 Zeile in der Ergebnismenge vorhanden ist. –

Verwandte Themen