光滑3多个外连接

时间:2015-08-17 23:59:10

标签: scala playframework-2.0 slick

来自Slick文档,它清楚如何在两个表之间进行单个左连接。

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

q q将如预期的那样具有_1类型的Titles和类型_2的{​​{1}}属性,以涵盖不存在的卷。

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

Rep[Option[Volumes]]

由于val q = for { ((t, v), c) <- titles joinLeft volumes on (_.uid === _.titleUid) joinLeft chapters on (_._2.uid === _.volumeUid) } yield /* etc. */ _._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

1 个答案:

答案 0 :(得分:25)

您的第二个左连接不再在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)