考虑模型:
Player
name Text
nick Text
email Text Maybe
phone Text Maybe
note Textarea Maybe
minutes Int Maybe
deriving
Table
name Text
game Text
pointsHour Int
seats Int Maybe
description Text Maybe
deriving
GamingSession
start UTCTime
end UTCTime Maybe
player PlayerId
table TableId
seat Int Maybe
deriving
和功能
getGamingSessionsR :: Handler RepHtml
getGamingSessionsR = do
sessions <- runDB $ selectList [GamingSessionEnd ==. Nothing] [Desc GamingSessionTable]
defaultLayout $(widgetFile ("opensessions"))
如何获得每个相关会话的所有播放器名称?
操作
players <- runDB $ selectList [FilterOr . map (\(Entity _ s) -> PlayerId ==. (GamingSessionPlayer s)) $ sessions] []
获取玩家名单;但它与所有会议无关
答案 0 :(得分:6)
此时持久性的连接支持有限,我相信它只是SQL。
我有几个帮助我用于简单的案例。他们可以找到here。这不是一个真正的JOIN,它每个表选择一次,然后构建一个元组列表,表示“连接”行,每个元素都有一个元素。
鉴于您的模型和助手,您应该能够执行以下操作:
records <- runDB $ do
sessions <- selectList [] []
players <- selectList [] []
tables <- selectList [] []
return $ joinTables3 gamingSessionPlayer gamingSessionTable sessions players tables
forM records $ \(session, player, table) -> do
--
-- ...
--
只有在所有三个表中都存在记录的情况才会被返回(因此它是一个内部联接),但您可能也希望对效率进行预过滤。
答案 1 :(得分:3)
为了将来参考,对于sql,您可以使用esqueleto或rawSQL进行连接 - 请参阅此答案Baffled by selectOneMany in Yesod
如果您想使用联接,请在esqueleto中查询类似于:
select $ from $ \(gamingSession `InnerJoin` player) -> do
on (gamingSession ^. GamingSessionPlayer ==. player ^. PlayerId)
where_ $ isNothing $ gamingSession ^. GamingSessionEnd
orderBy [asc (gamingSession ^. GamingSessionTable)]
return (gamingSession, player ^. PlayerId)
这将返回(Entity GamingSession,PlayerId)元组