8

我有一个包含教师、学校和学区的数据库模式。该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 来表达吗?如果是这样,怎么做?

4

1 回答 1

3

尝试改变

 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 期望 a 的可能性,PersistNull并且查询对我来说很好。

于 2015-01-26T02:16:50.383 回答