无法使用Esqueleto编写双左连接

时间:2015-01-24 01:10:13

标签: haskell esqueleto

我有一个教师,学校和地区的数据库架构。 TEACHERS表格有一个可以为空的SCHOOL_ID列(教师可能属于也可能不属于某个学校),SCHOOLS表格可以为DISTRICT_ID列(学校可以或者可能不属于某个地区。)

使用Esqueleto,我想要一份教师名单,每名教师都有一所学校(如果他们属于一所学校)和一个学区(如果他们属于属于学区的学校)。花了一点时间才找出适合老师的正确表达式 - >学校离开加入,但我最终做对了:

select $
from $ \(teacher `LeftOuterJoin` school) -> do
  on (teacher ^. TeacherSchoolId  ==. school ?. SchoolId)
  return (teacher, school)

我尝试使用类似的表达式在DISTRICTS上添加另一个左连接:

select $
from $ \(teacher `LeftOuterJoin` school `LeftOuterJoin` district) -> do
  on (school  ^. SchoolDistrictId ==. district ?. DistrictId)
  on (teacher ^. TeacherSchoolId  ==. school   ?. SchoolId)
  return (teacher, school, district)

但是我收到了一个错误:

Couldn't match type ‘Entity School’ with ‘Maybe (Entity School)’
Expected type: SqlExpr (Maybe (Entity School))
  Actual type: SqlExpr (Entity School)
In the first argument of ‘(?.)’, namely ‘school’
In the second argument of ‘(==.)’, namely ‘school ?. SchoolId’

可以使用Esqueleto表达此双连接吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:2)

尝试更改

 on (teacher ^. TeacherSchoolId  ==. school   ?. SchoolId)

 on (teacher ^. TeacherSchoolId  ==. just (school   ?. SchoolId))

如果这不起作用,请在查询表达式的其他组件上“正好”,直到它起作用。

参考:最近在商业项目中使用Esqueleto

更新,2016/10/26:

我最近遇到过这个问题。我认为这是一个持久的序列化问题,与Esqueleto交互假装连接的意愿不会产生可空的结果。

我最近更改了一个查询片段:

  person  `LeftOuterJoin`
  personExtra
 ) -> do
  on ((personExtra ^. PersonExtraPerson) ==. (person ^. PersonId))

为:

  person  `LeftOuterJoin`
  personExtra
 ) -> do
  on ((personExtra ?. PersonExtraPerson) ==. just (person ^. PersonId))

我还将查询的返回类型从Entity PersonExtra更改为Maybe (Entity PersonExtra)

现在Persistent期望PersistNull的可能性,并且查询对我来说很好。