我有一个教师,学校和地区的数据库模式.该TEACHERS表具有可以为空的SCHOOL_ID列(教师可能属于或可能不属于学校),并且该SCHOOLS表具有可为空的DISTRICT_ID列(学校可能属于或可能不属于某个区).
使用Esqueleto,我想要一个教师名单,每个教师都有一所学校(如果他们属于一所学校)和一个学区(如果他们属于属于某个学区的学校).花了一点时间才找出适合老师的正确表达 - >学校左连接,但我最终做对了:
select $
from $ \(teacher `LeftOuterJoin` school) -> do
on (teacher ^. TeacherSchoolId ==. school ?. SchoolId)
return (teacher, school)
Run Code Online (Sandbox Code Playgroud)
我尝试DISTRICTS使用类似的表达式添加另一个左连接:
select $
from $ \(teacher `LeftOuterJoin` school `LeftOuterJoin` district) -> do
on (school ^. SchoolDistrictId ==. district ?. DistrictId)
on (teacher ^. TeacherSchoolId ==. school ?. SchoolId)
return (teacher, school, district)
Run Code Online (Sandbox Code Playgroud)
但是我收到一个错误:
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’
Run Code Online (Sandbox Code Playgroud)
可以使用Esqueleto表示这种双连接吗?如果是这样,怎么样?
Try changing
on (teacher ^. TeacherSchoolId ==. school ?. SchoolId)
Run Code Online (Sandbox Code Playgroud)
To
on (teacher ^. TeacherSchoolId ==. just (school ?. SchoolId))
Run Code Online (Sandbox Code Playgroud)
If that doesn't work, slap 'just' on other components of the query expression until it works.
Reference: used Esqueleto recently on a commercial project
Update, 2016/10/26:
I recently encountered this problem. I think it's a Persistent serialization problem interacting with Esqueleto's willingness to pretend the join doesn't produce nullable results.
I recently changed a fragment of a query from:
person `LeftOuterJoin`
personExtra
) -> do
on ((personExtra ^. PersonExtraPerson) ==. (person ^. PersonId))
Run Code Online (Sandbox Code Playgroud)
to:
person `LeftOuterJoin`
personExtra
) -> do
on ((personExtra ?. PersonExtraPerson) ==. just (person ^. PersonId))
Run Code Online (Sandbox Code Playgroud)
I also changed the return type of my query from Entity PersonExtra to Maybe (Entity PersonExtra).
Now Persistent expects the possibility of a PersistNull and the query works fine for me.