>我有一个DBIO[Seq[tuple]]
,我想将其映射到DBIO[Seq[customCaseClass]]
。
我知道我可以用这样的东西对db.run()
结果进行转换:customCaseClass.tupled(row)
(见这个答案(。但是,我对在不同的函数中组合DBIO
返回值感兴趣。
有三个地方可以执行此操作: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
。Essential Slick 的第 5.2 节对此提供了更多详细信息。
二元
这个问题是专门关于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)
,因此可以决定要对这些值执行的操作。 - 成为行动的一部分意味着你可以参与一个转换。
Essential Slick的第4章列出了许多DBIO组合器。光滑手册还描述了组合器。
前途
最后一个地方在Future
,它看起来非常像DBIO
版本,但在db.run
之后(正如您已经发现的那样(。