2

ScalaQuery のクエリ チュートリアルに従っていると、よくわからない興味深いことがわかりました。

定義されたデータベーススキーマは次のとおりです。

object Users extends Table[(Int, String, String)]("users") {
    def id = column[Int]("id", O NotNull)
    def first = column[String]("first", O NotNull)
    def last = column[String]("last", O NotNull)
    def * = id ~ first ~ last 
}

そして、ここに私が使用するクエリがあります:

object Main
{
    val database = Database.forURL("jdbc:sqlite:sample.db", driver = "org.sqlite.JDBC")
    def main(args: Array[String]) {
        database withSession {

            val query1 = for (user <- Query(Users)) yield user.id ~ user.last
            val query2 = for (user <- Users if user.id > 5) yield user.id ~ user ~ last
        }
    }
}

この場合、両方で のようなものquery1query2使用していることがわかります。これはuser.id、先ほど定義したuserシングルトンのタイプのようです。object Usersしたがって、そのオブジェクトで定義されたすべてのメソッドがあります。

しかし、キーワードなしでクエリを直接実行しようとするとyield、たとえば次のようになります。

for (user <- Users if user.id > 5) {
    println ("UserID:" + user.id)
}

この場合、コンパイラは次のように文句を言います。

[error] src/main/scala/Test.scala:23: value id is not a member of (Int, String, String)
[error]    println ("UserID:" + user.id)

userprintln ステートメントは Tuple3 のタイプのようです。そしてuser、次のような通常のタプルのように使用すると、機能します。

for (user <- Users if user.id > 5) {
    println ("UserID:" + user._1)
}

そして、私がまだ使用している for 式のガードでuser.id、 の型はuser何ですか? user.idガードブロックとイールドブロックで使用できるのに、for 式の本体でタプルとして使用する必要があるのはなぜですか?

ありがとう。

4

1 に答える 1

7

最初のコードスニペット:

val query1 = for (user <- Query(Users)) yield user.id ~ user.last

userobject Usersクエリのマップメソッドがとして定義されているためdef map[F](f: E => F): Query[F]、最初のコードスニペットは次のようになります。

Query(Users).map(user => user.id ~ user.last)

したがって、EはのUsersタイプであり、Usersインスタンスはに与えるパラメータf(E):Fです。

行をオブジェクトとして訪問する場合は、次のようにユーザーを定義する必要があります。

import org.scalaquery.ql.basic.{BasicTable => Table}
object Users extends Table[User]("users") {
  def id = column[Int]("id", O NotNull)
  def first = column[String]("first", O NotNull)
  def last = column[String]("last", O NotNull)
  def * = id ~ first ~ last <> (User, User.unapply _)
}

case class User(id: Int, first: String, last: String)

その後

for (user <- Users if user.id > 5) {
  println ("UserID:" + user.id)  // user is a User instance
}
于 2011-03-28T06:53:20.650 に答える