返回`也许(实体)从``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 Inventory
为Maybe (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
然后都i
和is
(库存SKU表)应与语法的投射:
on $ i ?. InventoryId ==. is ?. InventorySkuItem
on $ cs ^. ContainerSlotItem ==. i ?. InventoryId