【问题标题】:in Slick 3.0, how to I get from a query to a case class?在 Slick 3.0 中,如何从查询到案例类?
【发布时间】:2015-04-19 22:37:40
【问题描述】:

我正在尝试在 Scala 应用程序中将 Slick 用于数据库,但遇到了一些关于如何查询(查找)并将结果转换为案例类的问题(或我的误解)。

我不是在映射案例类,而是映射实际值,目的是动态创建案例类。所以,我的桌子是:

object Tables {

  class Names(tag: Tag) extends Table[Name](tag, "NAMES") {
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
        def first = column[String]("first")
        def middle = column[String]("last")
        def last = column[String]("last")

        def * = (id.?, first, middle.?, last) <> ((Name.apply _).tupled, Name.unapply)
  }

  object NamesQueries {

    lazy val query = TableQuery[Names]

    val findById = Compiled { k: Rep[Long] =>
      query.filter(_.id === k)
    }
  }
}

这里是查询:

object NamesDAO {

  def insertName(name: Name) {
    NamesQueries.query += name.copy(id = None)
  }

  def findName(nameId: Long) = {
    val q = NamesQueries.findById(nameId)                         // AppliedCompiledFunction[Long, Query[Tables.Names, Tables.Names.TableElementType, Seq],Seq[Tables.Names.TableElementType]]
    val resultSeq = Database.forConfig("schoolme").run(q.result)  // Future[Seq[Tables.Names.TableElementType]]
    val result = resultSeq.map { r =>                             // val result: Future[(Option[Long], String, Option[String], String) => Name]
      val rr = r.map{ name =>                                     // val rr: Seq[(Option[Long], String, Option[String], String) => Name]
        Name.apply _
      }
      rr.head
    }
    result
  }
}

但是,findName 方法似乎返回 Future((Option[Long], String, Option[String], String) =&gt; Name) 而不是 Future(Name)。我究竟做错了什么?只是使用asInstanceOf[Name]的问题吗?

编辑:按照 sap1ens 的建议,将 findName 扩展为每个带有 cmets 的小块。

【问题讨论】:

  • 可能值得将 findName 方法拆分为多行并使用显式类型...至少对于调试而言,它会更容易理解。

标签: scala slick-3.0


【解决方案1】:

好吧,我会被诅咒的。 在上面的 sap1ens 评论之后,我将 findName 分解为多个步骤(并编辑了问题)。但在那之后,我回去给我的 val 一个明确的类型,这很有效。看这里:

  def findName(nameId: Long) = {
    val q = NamesQueries.findById(nameId)                        
    val resultSeq: Future[Seq[Name]] = Database.forConfig("schoolme").run(q.result)  
    val result = resultSeq.map { r =>
      val rr = r.map{ name =>
        name
      }
      rr.head
    }
    result
  }

所以,类型推断是这次 (/my) 的罪魁祸首。记住,记住。

【讨论】:

  • 只是一个旁注,以节省几行代码:r.map { name =&gt; name } 实际上什么也没做。您只需将Seq[Name] 映射到另一个Seq[Name]。要仅获得第一个结果,您可以编写val result = resultSeq.map(r =&gt; r.head),它可以更简洁地表示为val result = resultSeq.map(_.head)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多