Slick 3 多个外部连接
Slick 3 multiple outer joins
从 Slick 文档中可以清楚地了解如何在两个表之间进行单个左连接。
val q = for {
(t, v) <- titles joinLeft volumes on (_.uid === _.titleUid)
} yield (t, v)
查询 q 将如预期的那样具有属性:Titles
类型的 _1
和 Rep[Option[Volumes]]
类型的 _2
以覆盖不存在的卷。
进一步级联有问题:
val q = for {
((t, v), c) <- titles
joinLeft volumes on (_.uid === _.titleUid)
joinLeft chapters on (_._2.uid === _.volumeUid)
} yield /* etc. */
这行不通,因为 _._2.uid === _.volumeUid
无效,因为 _.uid
不存在。
根据网络上的各种来源,这应该不是问题,但话又说回来,来源往往针对不同的 slick 版本,而 3.0 仍然是相当新的。有人对这个问题有一些线索吗?
澄清一下,想法是使用两个左连接从 3 个级联 1:n:n 表中提取数据。
等效的 SQL 将是:
Select *
from titles
left join volumes
on titles.uid = volumes.title_uid
left join chapters
on volumes.uid = chapters.volume_uid
您的第二个左联接不再在 TableQuery[Titles]
上运行,而是在有效的 Query[(Titles, Option[Volumes])]
上运行(忽略结果和集合类型参数)。当您在 TableQuery[Chapters]
上加入结果查询时,您可以使用 _2
字段访问元组中的第二个条目(因为它是一个 Option
,您需要 map
访问 uid
字段):
val q = for {
((t, v), c) <- titles
joinLeft volumes on (_.uid === _.titleUid)
joinLeft chapters on (_._2.map(_.uid) === _.volumeUid)
} yield /* etc. */
避免TupleN
如果 _N
字段语法不清楚,您也可以使用 Slick's capacity for user-defined record types 来映射您的行:
// The `Table` variant of the joined row representation
case class TitlesAndVolumesRow(title: Titles, volumes: Volumes)
// The DTO variant of the joined row representation
case class TitleAndVolumeRow(title: Title, volumes: Volume)
implicit object TitleAndVolumeShape
extends CaseClassShape(TitlesAndVolumesRow.tupled, TitleAndVolumeRow.tupled)
从 Slick 文档中可以清楚地了解如何在两个表之间进行单个左连接。
val q = for {
(t, v) <- titles joinLeft volumes on (_.uid === _.titleUid)
} yield (t, v)
查询 q 将如预期的那样具有属性:Titles
类型的 _1
和 Rep[Option[Volumes]]
类型的 _2
以覆盖不存在的卷。
进一步级联有问题:
val q = for {
((t, v), c) <- titles
joinLeft volumes on (_.uid === _.titleUid)
joinLeft chapters on (_._2.uid === _.volumeUid)
} yield /* etc. */
这行不通,因为 _._2.uid === _.volumeUid
无效,因为 _.uid
不存在。
根据网络上的各种来源,这应该不是问题,但话又说回来,来源往往针对不同的 slick 版本,而 3.0 仍然是相当新的。有人对这个问题有一些线索吗? 澄清一下,想法是使用两个左连接从 3 个级联 1:n:n 表中提取数据。 等效的 SQL 将是:
Select *
from titles
left join volumes
on titles.uid = volumes.title_uid
left join chapters
on volumes.uid = chapters.volume_uid
您的第二个左联接不再在 TableQuery[Titles]
上运行,而是在有效的 Query[(Titles, Option[Volumes])]
上运行(忽略结果和集合类型参数)。当您在 TableQuery[Chapters]
上加入结果查询时,您可以使用 _2
字段访问元组中的第二个条目(因为它是一个 Option
,您需要 map
访问 uid
字段):
val q = for {
((t, v), c) <- titles
joinLeft volumes on (_.uid === _.titleUid)
joinLeft chapters on (_._2.map(_.uid) === _.volumeUid)
} yield /* etc. */
避免TupleN
如果 _N
字段语法不清楚,您也可以使用 Slick's capacity for user-defined record types 来映射您的行:
// The `Table` variant of the joined row representation
case class TitlesAndVolumesRow(title: Titles, volumes: Volumes)
// The DTO variant of the joined row representation
case class TitleAndVolumeRow(title: Title, volumes: Volume)
implicit object TitleAndVolumeShape
extends CaseClassShape(TitlesAndVolumesRow.tupled, TitleAndVolumeRow.tupled)