首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >selectOneMany Yesod持久性

selectOneMany Yesod持久性
EN

Stack Overflow用户
提问于 2012-07-20 07:30:03
回答 2查看 705关注 0票数 3

我正在尝试让selectOneMany工作,但只取得了有限的成功。

我有以下数据库模型

代码语言:javascript
复制
User
 email Text
 verkey Text Maybe
 verified Bool
 password Text Maybe
 UniqueUser email
 date UTCTime
 deriving Show

Competence
 parent CompetenceId Maybe
 title Text
 UniqueCompetence title
 deriving Show Read

UserCompetence
 competence CompetenceId
 user UserId Eq
 UniqueUserCompetence user competence
 deriving Show Read

来自我的处理程序的代码

代码语言:javascript
复制
mmember <- runMaybeT $ do
  id <- MaybeT $ maybeAuth
  user <- MaybeT . runDB . get . entityKey $ id
  Entity memberId member <- MaybeT . runDB . getBy . UniqueMember . userEmail $ user
  competences <- lift . runDB . runJoin $ (selectOneMany (UserCompetenceUser <-.) userCompetenceUser)
  return (member,competences)

首先,如果不添加一个大的类型签名,我不能让这段代码运行,这是它应该是的吗?

代码语言:javascript
复制
competences <- lift . runDB . runJoin $ (selectOneMany (UserCompetenceUser <-.) userCompetenceUser :: SelectOneMany SqlPersist (UserGeneric SqlPersist) (UserCompetenceGeneric SqlPersist))

其次,什么是能力类型。理想情况下,我希望最终拥有Entity competenceId能力。

最后,如何在上面的连接中添加一个筛选器,以便只获取“user”的能力?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-20 08:29:33

我已经告诉过您,由于SelectOneMany使用的类型别名可能不是归纳的,因此不可能避免额外的类型签名;即,您的代码试图比其应有的多态程度更高,而类型签名对于限制这种多态是必要的。

你可以通过“从不同的角度”约束类型来避免使用巨大的签名,例如:

代码语言:javascript
复制
return (member, competences :: [(Entity User, [Entity UserCompetence])])

由于类型别名UserUserCompetence选择特定的数据库后端,因此应该适当地解析这些类型。

另外,我刚刚为你破坏了competences的类型。哈哈!我希望这对你来说足够了。如果你想要一个多对多的三表连接,这样你就可以让一个用户拥有所有的能力,你无论如何都应该使用准备好的语句,因为潜在的AST开销,所以看看the generic raw SQL interface,它让你做传统的"SELECT * FROM foo WHERE bar = ?" [filteredBarValue],你可能更习惯使用它;它不像persistent的其余部分提供相同的类型安全性,但我认为这是在你的情况下实现三表连接的最简单的方法。

您可以通过修改User类型为OneFilterManyoneFilterMany的结果来限制所选的OneFilterMany。就像这样(还没有测试过,但应该可以工作):

代码语言:javascript
复制
let join = (selectOneMany (UserCompetenceUser <-.) userCompetenceUser)
           { somFilterOne = [... filters for User ...] }
competences <- lift . runDB . runJoin $ join
票数 2
EN

Stack Overflow用户

发布于 2012-07-21 03:37:41

多亏了dflemstr的(很多)帮助,我最终得到了

代码语言:javascript
复制
mmember <- runMaybeT $ do
  id <- MaybeT $ maybeAuth
  let user = entityVal id
  Entity memberId member <- MaybeT . runDB . getBy . UniqueMember . userEmail $ user
  let competenceStatement =
        Text.concat
        [ "SELECT ?? "
        , "FROM   competence,     user_competence "
        , "WHERE  competence.id = user_competence.competence_id "
        , "AND    ?             = user_competence.user_id"
        ]
  competences <- lift . runDB $ rawSql competenceStatement
                 [toPersistValue . entityKey $ id]
  return (member, competences :: [Entity Competence])
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11570800

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档