我有一个DBIO[Seq[tuple]]
,我想将其映射到DBIO[Seq[customCaseClass]]
。
我知道我可以对db.run()
结果进行转换,例如:customCaseClass.tupled(row)
(see this answer)。但是,我有兴趣在各种函数中组成DBIO
返回值。
答案 0 :(得分:1)
您可以在三个地方进行此操作:Query
级别,DBIO
级别,以及Future
级别(如您所指出并拒绝的)。
在查询级别,转换将作为在Slick自己的执行上下文上执行查询的一部分进行。
它看起来像这样:
// Given some query that returns a tuple...
val tupleQ: Query[(Rep[String],Rep[String]), (String,String), Seq] =
table.map{ row => (row.column1, row.column2) }
// ...which we'd like to project into this:
case class SomeCaseClass(v1: String, v2: String)
// ...we can use the mapTo macro to generate the conversion:
val ccQ: Query[Rep[SomeCaseClass], SomeCaseClass, Seq] =
tupleQ.map{ _.mapTo[SomeCaseClass] }
如果这就是您要做的一切,那么也许可以使用默认投影(def * ...
)。
如果您需要对转换逻辑的更多控制,则可以使用较低级别的<>
代替mapTo
。 Section 5.2 of Essential Slick对此提供了更多详细信息。
问题特别是关于DBIO
。那里的转换将在您自己的执行上下文中运行。
这看起来像这样:
// Given a DBIO that returns a tuple...
val tupleD: DBIO[Seq[(String,String)]] =
table.map(row => (row.column1, row.column2)).result
// ... we can use any of the DBIO combinators to convert it, such as map:
val ccD: DBIO[Seq[SomeCaseClass]] =
dQ.map{ pairs => pairs.map{ case (a, b) => SomeCaseClass(a,b) } }
(...或您注意到的dQ.map(pairs => pairs.map(SomeCaseClass.tupled))
。)
在此级别上获得的两个大好处是:
(a,b)
,因此可以决定要使用这些值做什么。Chapter 4 of Essential Slick列出了许多DBIO组合器。 Slick Manual还描述了组合器。
最后一个地方是Future
,它看起来很像DBIO
版本,但在db.run
之后(如您所见)。