如何使用多个联接,联接类型,条件

时间:2017-10-19 13:53:18

标签: scala slick dry

我有一堆不同的查询可以获取相同的数据,但是应用了不同的标准。

目前,我正在将整个代码库从Query复制到DBIOAction,因为我无法看到如何使这些可组合。这是重复查询的一个示例。

(我已经简化了一些示例,实际代码连接了十三个表):

  override val createAction = {

    val join = master
      .join(child1.filter(child1Filter)).on(_.id === _.id)  /* DRY1 */
      .joinLeft(child2).on(_._1.id === _.id)
      .joinLeft(child3).on(_._1._1.id === _.id)
      .joinLeft(child4).on(_._1._1._1.id === _.id)
      .joinLeft(child5).on(_._1._1._1._1.id === _.id)
      .joinLeft(child6).on(_._1._1._1._1._1.id === _.id)

    val query = for {
      ((((((r, c1), c2), c3), c4), c5), c6) <- join
    } yield (r.id, c1.value, c2.value, c3.value, c4.value, c5.value, c6.value)  /* DRY2 */

    query.result.map( tuples =>
        tuples.groupBy(_._1)
          .map {
          case(id, tuples) => {
            val c1 = tuples.map(_._2).distinct.head /* DRY3 */
            val c2 = tuples.map(_._3).distinct.head
            val c3 = tuples.flatMap(_._4).distinct.headOption
            val c4 = tuples.flatMap(_._5).distinct.headOption
            val c5 = tuples.flatMap(_._6).distinct.headOption
            val c6 = tuples.flatMap(_._7).distinct.headOption

            SomeCaseClass(c1, c2, c3, c4, c5, c6)
          }
      }
    )
  }  

我已经标记了三个部分,其中过滤条件中的一个更改只会更改代码:

DRY1 - 在任何一个加入条件下,我们可以选择joinLeft或仅join。这会产生分歧,因为生成的join具有不同的参数化类型。我们可能还想添加其他标准。

DRY2 - c1的类型取决于之前加入的类型。

DRY3 - 同样,连接类型会影响结果的映射方式和案例类的创建。

举例来说,一个查询会更改child1上的联接,另一个查询会更改child2上的联接。

我缺少一些可以组合并且不会违反DRY的更复杂查询的例子。

0 个答案:

没有答案