haskell - 无法使用 Esqueleto 编写双左连接

标签 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 来表达吗?如果是这样,怎么办?

最佳答案

尝试改变

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

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

如果这不起作用,请“只是”查询表达式的其他组件,直到它起作用为止。

引用:最近在一个商业项目中使用了Esqueleto

更新,2016/10/26:

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

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

  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 的可能性,并且该查询对我来说工作正常。

关于haskell - 无法使用 Esqueleto 编写双左连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28121228/

相关文章:

haskell - 使用 Esqueleto 进行外部连接

haskell - Esqueleto 简单类型错误

sql - 选择内的 Esqueleto 计数

haskell - 用 Monad 的 Applicative 来定义 Functor 更好,反之亦然?

haskell - 在什么情况下通用子表达式消除会影响 Haskell 程序的惰性?

haskell - 类似的 Haskell 列表推导式具有不同的结果

haskell - Haskell 树上折叠的变化

haskell - 为什么您不能(完全)应用具有使用其他类型同义词的参数的类型同义词?

haskell - 如何使用 Esqueleto 执行 "SELECT ... IN (SELECT ...)"?