光滑3多个外连接

Bru*_*elo 14 scala playframework-2.0 slick

从Slick文档中,很清楚如何在两个表之间进行单个左连接.

val q = for {
  (t, v) <- titles joinLeft volumes on (_.uid === _.titleUid)
} yield (t, v)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,查询q将具有属性:_1类型Titles_2类型,Rep[Option[Volumes]]以涵盖不存在的卷.

进一步的级联是有问题的:

val q = for {
  ((t, v), c) <- titles 
                     joinLeft volumes on (_.uid === _.titleUid)
                     joinLeft chapters on (_._2.uid === _.volumeUid)
} yield /* etc. */
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为_._2.uid === _.volumeUid如果_.uid不存在则无效.

根据网上的各种消息来源,这不应该是一个问题,但是再一次,消息来源倾向于针对不同的光滑版本而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
Run Code Online (Sandbox Code Playgroud)

Sea*_*ira 26

你的第二个左连接不再在a 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. */
Run Code Online (Sandbox Code Playgroud)

避免 TupleN

如果_N字段语法不清楚,您还可以将Slick的容量用于用户定义的记录类型交替映射行:

// 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)
Run Code Online (Sandbox Code Playgroud)