我有一个数据库,其中包含具有一对多注册关系的活动.目标是通过一系列注册来获取所有活动.
通过创建具有注册的活动的笛卡尔积,可以获得用于获取该数据的所有必要数据.但我似乎无法找到一个很好的方法将它正确地放入scala集合中; 让我们的类型:Seq[(Activity, Seq[Registration])]
case class Registration(
id: Option[Int],
user: Int,
activity: Int
)
case class Activity(
id: Option[Int],
what: String,
when: DateTime,
where: String,
description: String,
price: Double
)
Run Code Online (Sandbox Code Playgroud)
假设存在适当的光滑表和表查询,我会写:
val acts_regs = (for {
a <- Activities
r <- Registrations if r.activityId === a.id
} yield (a, r))
.groupBy(_._1.id)
.map { case (actid, acts) => ??? }
}
Run Code Online (Sandbox Code Playgroud)
但我似乎无法做出适当的映射.这样做的惯用方法是什么?我希望它比使用原始笛卡尔产品更好......
在scala代码中,它很容易,看起来像这样:
val activities = db withSession { implicit sess =>
(for {
a <- Activities leftJoin Registrations on (_.id === _.activityId)
} yield a).list
}
activities
.groupBy(_._1.id)
.map { case (id, set) => (set(0)._1, set.map(_._2)) }
Run Code Online (Sandbox Code Playgroud)
但是由于表映射器将为您创建的Activity的不必要的实例化,这似乎相当低效.它看起来也不是很优雅......
当scala方法只对这样的注册计数感兴趣时更糟糕:
val result: Seq[Activity, Int] = ???
Run Code Online (Sandbox Code Playgroud)
我在浮油中的最佳尝试看起来像这样:
val activities = db withSession { implicit sess =>
(for {
a <- Activities leftJoin Registrations on (_.id === _.activityId)
} yield a)
.groupBy(_._1.id)
.map { case (id, results) => (results.map(_._1), results.length) }
}
Run Code Online (Sandbox Code Playgroud)
但这会导致一个错误,即光滑无法映射"map"-line中的给定类型.
我会建议:
val activities = db withSession { implicit sess =>
(for {
a <- Activities leftJoin Registrations on (_.id === _.activityId)
} yield a)
.groupBy(_._1)
.map { case (activity, results) => (activity, results.length) }
}
Run Code Online (Sandbox Code Playgroud)
这个问题
val activities = db withSession { implicit sess =>
(for {
a <- Activities leftJoin Registrations on (_.id === _.activityId)
} yield a)
.groupBy(_._1.id)
.map { case (id, results) => (results.map(_._1), results.length) }
}
Run Code Online (Sandbox Code Playgroud)
是你不能在group by中生成嵌套结果.results.map(_._1)
是一个项目的集合.在某些情况下,SQL会执行从集合到单行的隐式转换,但Slick是类型安全的.你想在Slick做什么results.map(_._1).head
,但目前不支持.你能得到的最接近的东西就是这样(results.map(_.id).max, results.map(_.what).max, ...)
,这很乏味.因此,整个活动行的分组可能是目前最可行的解决方法.
归档时间: |
|
查看次数: |
5474 次 |
最近记录: |