将 DBIO 值转换为自定义案例类



>我有一个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))如您所指出的(。

您在此级别获得的两大好处是:

  1. 您可以访问这些值,例如(a,b),因此可以决定要对这些值执行的操作。
  2. 成为行动的一部分意味着你可以参与一个转换。

Essential Slick的第4章列出了许多DBIO组合器。光滑手册还描述了组合器。

前途

最后一个地方在Future,它看起来非常像DBIO版本,但在db.run之后(正如您已经发现的那样(。

最新更新