Слизированное внешнее соединение с несколькими таблицами

Выполнение внешнего соединения между двумя таблицами легко:

tblA.leftJoin(tblB).on(_.aId === _.bId)

Но при выполнении соединений между 5 таблицами он быстро становится громоздким:

tblA.leftJoin(tblB).on(_.aId === _.bId).
    leftJoin(tblC).on(_._1.aId === _.cId).
    leftJoin(tblD).on(_._1._1.aId === _.dId).
    leftJoin(tblE).on(_._1._1._1.aId === _.eId)

Аксесуары кортежей немного запутываются, особенно если они не все получают доступ к первой таблице.

Есть ли лучший способ?

Тот факт, что внутренние объединения семантически эквивалентны flatMap с фильтром, решает эту проблему для внутренних объединений:

for {
    a <- tblA
    b <- tblB if a.aId === b.bId
    c <- tblC if a.aId === c.cId
    d <- tblD if a.aId === d.dId
    e <- tblE if a.aId === e.eId
} yield ???

Есть ли similairly элегантный синтаксис для внешних соединений?

Ответ 1

Как насчет этого?

tblA.leftJoin(tblB).leftJoin(tblC).leftJoin(tblD).leftJoin(tblE).on{
  case ((((a,b),c),d),e) =>
    a.aId === b.bId &&
    a.aId === c.cId &&
    a.aId === d.dId &&
    a.aId === e.eId
}

В настоящий момент не создается лучший SQL, но мы надеемся, что это будет скоро.

Левое объединение, создающее HLists, должно позволить даже сделать паттерн лучше, но, вероятно, заблокировано: https://github.com/slick/slick/issues/728