2012-02-22 64 views
3

说,在耶索德/持续性,我有模特的设置,像这样:耶索德/持续一到一个查询

User 
    ident Text 
    password Text Maybe 
    UniqueUser ident 
Question 
    title Text 
    asker UserId Eq 

而且我有Question秒的列表,并想获取相应的列表的User s。我会如何去做这件事?我想过关于连接,但这些是一对多,而不是一对一(我想这不重要,但我想要一个更简单的解决方案)。手工做的加入也是一种选择,但我担心的表现 - 我有

questions <- runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10] 
let askerIds = map (\(Entity _ q) -> questionAsker q) questions 
askers <- sequence $ map (runDB . get) askerIds 
let questionsAndAskers = zip questions askers 

,但我很担心在map(那岂不是对数据库的一个单独的请求使用runDB每个用户?)

是否有更好/更习惯性的方式来实现这一目标?

+0

是的我认为这是公平的假设,每次你碰到'runDB',将执行另一个数据库查询。 – 2012-02-22 14:51:46

回答

6

我还没有进行类型检查这个,但我会坚持整件事的runDB内:

runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10] >>= mapM (\[email protected](Entity _ q) -> do 
    asker <- get $ questionAsker q 
    return (qe, asker)) 
+0

所以持续有N + 1选择,而不是1? – Qrilka 2013-04-02 07:04:44

+1

是的,按照制定。如果你想有一个单一的查询,你需要使用连接。为此,我建议使用esqueleto。 – 2013-04-02 07:13:03

+0

谢谢esqeleto看起来很有前途 – Qrilka 2013-04-02 07:32:53

1

如何:

questions <- runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10] 
let askerIds = map (\(Entity _ q) -> questionAsker q) questions 
askers <- runDB $ selectList [UserId <-. askerIds] [] 
let questionsAndAskers = zip questions askers 

这似乎像它应该打在DB一次为用户。

+1

如果我没有弄错,第二行可能写成'let askersIds = map(questionAsker。entityVal)questions',我发现它更具可读性。 – 2012-07-14 14:28:14