Haskell 从Esqueleto'LeftOuterJoin返回'Maybe(实体a)``
从脚手架站点中的人工Haskell 从Esqueleto'LeftOuterJoin返回'Maybe(实体a)``,haskell,yesod,persistent,esqueleto,Haskell,Yesod,Persistent,Esqueleto,从脚手架站点中的人工config/models: Inventory name Text description Text Container name Text ContainerSlot container ContainerId item InventoryId Maybe 现在,使用Esqueleto,我想使用LeftOuterJoin获取容器中的插槽,如果未分配实际库存,则实际库存为空 selectContainerS
config/models
:
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 :: Entity ContainerSlot -> Entity Inventory -> Result
当Inventory
字段被NULL
值填充时(可以预见),会导致运行时失败
PersistMarshalError "field id: int64 Expected Integer, received: PersistNull"
是否有办法将
实体清单
投影为可能(实体清单)
?这可能被标记为的副本;然而,不同之处在于投影
在处理任何外部联接时,所有可能返回null的表都应该使用语法进行所有投影。
语法。这将迫使表的实体变成Maybe(实体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
然后,应使用以下语法投影i
和is
(库存SKU表):
on $ i ?. InventoryId ==. is ?. InventorySkuItem
on $ cs ^. ContainerSlotItem ==. i ?. InventoryId
select $ from $ \(cs `LeftOuterJoin` (i `InnerJoin` is)) -> do
on $ i ?. InventoryId ==. is ?. InventorySkuItem
on $ cs ^. ContainerSlotItem ==. i ?. InventoryId