具有两个条件的三个表的左外连接在 Slick 中均不起作用

Left outer join of three tables with two conditions each not working in Slick

我想在 Slick 中表示以下左外连接:

select * from tableD d 
left outer join tableE e on e.ds_sk=d.ds_sk and e.ds_type = d.ds_type
left outer join tableV v on v.es_sk=e.sk and v.var_name=d.var_name
where e.sk=30;

请注意,每个关系都包含两个连接条件。第一个连接条件在tableDtableE之间,第二个连接条件在tableVtableEtableD之间。最后,还有一个 where 条件。

这是我的尝试(抛出编译错误):

  val query = for {
    ((d, e), v) <- tableE joinLeft tableD on ((x,y) => x.dsType === y.dsType && x.dsSk === y.dsSk) 
                          joinLeft tableV on ((x,y) => x._1.sk === y.esSk && x._2.varName === y.varName) 
                   if (e.sk === 30) 
  } yield (d,e,v)

我得到的错误是:

◾value varName is not a member of slick.lifted.Rep[Option[tableD]]

错误是什么以及如何修复此代码?

您可以通过 varName 比较 map,例如:

...  && x._2.map(_.varName) === y.varName ...

这里我举一个类似的例子:

  val withAddressesQuery = for {
   (((person, phone), _), address) <- withPhonesQuery.
           joinLeft(PersonAddress).on(_._1.personId === _.personId).
           joinLeft(Address).on(_._2.map(_.addressId) === _.addressId)
  } yield (person, phone, address)

注意:... on(_._2.map( _.addressId) === ...see complete

Chapter 6.4.3 of Essential Slick 中有更多关于 joinLeft 的信息。

您的 SQL 查询 (D leftjoin E leftjoin V) 和 Slick 查询 (E leftjoin D leftjoin V) 之间似乎存在差异。

假设您的 SQL 查询是正确的版本,Slick 查询应如下所示:

val query = for {
  ((d, e), v) <- tableD joinLeft tableE on ( (x, y) =>
                   x.dsType === y.dsType && x.dsSk === y.dsSk ) 
                        joinLeft tableV on ( (x, y) =>
                   x._2.map(_.sk) === y.esSk && x._1.varName) === y.varName ) 
                   if (e.sk === 30) 
  } yield (d,e,v)

请注意,在第二个 joinLeft 中,您需要使用 map 访问第一个 joinLeft 之后包裹在 Option 中的表 E 中的字段。这也解释了为什么您在 Slick 查询中收到有关 Option[tableD] 的错误消息。