返回`也许(实体)从``Esqueleto在脚手架网站LeftOuterJoin`

问题描述:

从做作config/models返回`也许(实体)从``Esqueleto在脚手架网站LeftOuterJoin`

Inventory 
    name  Text 
    description Text 
Container 
    name  Text 
ContainerSlot 
    container ContainerId 
    item  InventoryId Maybe 

现在,使用Esqueleto,我想用LeftOuterJoin得到插槽的容器,如果尚未分配实际库存,则清空。

selectContainerSlots containerKey = do 
    stuff <- select $ from $ \(cs `LeftOuterJoin` i) -> do 
    on $ cs ^. ContainerSlotItem ==. just (i ^. InventoryId) 
    where_ $ cs ^. ContainerSlotContainer ==. val containerKey 
    return (cs, i) 
    return $ uncurry buildStuff <$> stuff 

我希望buildStuff需要以下签名由于“外”性质的加盟:

buildStuff :: Entity ContainerSlot -> Maybe (Entity Inventory) -> Result 

,但发现它需要执行以下操作:

buildStuff :: Entity ContainerSlot -> Entity Inventory -> Result 

哪当(可预测)Inventory字段填充了NULL值时,会导致运行时失败。

PersistMarshalError "field id: int64 Expected Integer, received: PersistNull" 

是否有一个项目的Entity InventoryMaybe (Entity Inventory)方式?

这可能会标记为Outer Joins with Esqueleto;但是差异在于投影。

当处理任何外部联接时,所有可能返回空值的表应该有全部使用?.语法完成的预测。这将强制表的实体成为Maybe (Entity a)所以解决上面是

selectContainerSlots containerKey = do 
    stuff <- select $ from $ \(cs `LeftOuterJoin` i) -> do 
    on $ cs ^. ContainerSlotItem ==. i ?. InventoryId 
    where_ $ cs ^. ContainerSlotContainer ==. val containerKey 
    return (cs, i) 
    return $ uncurry buildStuff <$> stuff 

此外,如果超过一个表链接;例如

select $ from $ \(cs `LeftOuterJoin` (i `InnerJoin` is)) -> do 

然后iis(库存SKU表)应与语法的投射:

on $ i ?. InventoryId ==. is ?. InventorySkuItem 
    on $ cs ^. ContainerSlotItem ==. i ?. InventoryId