将postgres查询重写为NHibernate

时间:2015-01-21 19:34:41

标签: c# sql postgresql nhibernate fluent-nhibernate

请告诉我如何使用NHibernate的QueryOver<>()查询<>()或其他NHibernate方法来编写以下内容,这些方法不会让我重写此(以及许多其他类似的查询)切换数据库提供商?

具有多个表连接的子查询让我很难通过NHibernate的有限曝光进行翻译。

return Session.CreateSQLQuery("select " +
                               "    boards.id, boards.name, boards.description, " +
                               "    (" +
                               "        select " +
                               "            count(topic.id) " +
                               "        from topic " +
                               "        left join users on users.id=topic.user " +
                               "        left join boards b on b.id=topic.bid " +
                               "        left join boards b2 on b2.id=b.bid " +
                               "        where (topic.bid=boards.id or b.bid = boards.id or b2.bid = boards.id) " +
                               "        and (b.type <= (:userType)) " +
                               "        and (b2.type is null or b2.type <= (:userType)) " +
                               "        and users.type > 0 " +
                               "        and users.chatban = 0" +
                               "    ) as TopicCount," +
                               "    (" +
                               "        select (max(posts.time) - max(read.time)) as t " +
                               "        from posts " +
                               "        left join users u on u.id=posts.user" +
                               "        left join topic on topic.id=posts.tid " +
                               "        left join read on read.topic=topic.id and read.userid=(:userId) " +
                               "        left join boards b on b.id=topic.bid" +
                               "        left join boards b2 on b2.id=b.bid" +
                               "        where " +
                               "            (topic.bid=boards.id or b.bid = boards.id or b2.bid = boards.id) " +
                               "            and (b.type <= (:userType)) " +
                               "            and (b2.type is null or b2.type <= (:userType)) " +
                               "            and not exists (select boardid from boardhigh where boardid=b.id and userid=(:userId))" +
                               "            and u.type > 0 " +
                               "            and u.chatban = 0 " +
                               "        group by topic.id " +
                               "        order by t desc " +
                               "        limit 1" +
                               "    ) as time " +
                               "from boards " +
                               "left join topic on topic.bid=boards.id " +
                               "where" +
                               "    boards.type <= (:userType) " +
                               (parentBoard.HasValue ? " and boards.bid = " + parentBoard.Value : "") +
                               "group by boards.id, boards.name, boards.description, boards.display " +
                               "order by boards.display desc, boards.name asc"
            )
            .SetInt32("userType", (int)UserHelper.LoggedInUser.UserType)
            .SetInt64("userId", UserHelper.LoggedInUser.Id)
            .List()
            .Cast<object[]>()
            .ToList()
            .Select(x => new BoardValueObject
            {
                Id = (int)x[0],
                Name = x[1].ToString(),
                Description = x[2].ToString(),
                TopicCount = (long)x[3],
                Time = x[4] as int?
            })
            .ToList();

由于

1 个答案:

答案 0 :(得分:0)

我非常怀疑您是否已收到巨型SQL查询及其转换的答案。同时,我想指出使用NHibernate时方法/思维方面的一些差异。

  • 首先使用实体​​。使用UsersTopicsBoards定义您的模型,业务领域模型。
  • 花些时间了解延迟加载。可以通过简单查询获取大量数据以获取User(s),然后向他的主板,主题进行交流......所有需要的数据都将加载到分离的SQL语句中,但不需要复杂的查询。
  • 检查fo batch-loading的优点,这是一种如何避免1 + N SELECT问题的技巧。它确实运行良好,对发布的SQL语句数量产生了惊人的巨大影响。
  • 不要担心使用本机SQL来接收&#34; ...&#34;用户所需的数据(用疯狂,难以置信,复杂的单词替换点)。 NHibernate首先是ORM。它对于与Business对象模型相关的所有CRUD操作都做得很好。任何&#34; SP喜欢选择&#34;支持但间接支持......通过CreateSQLQuery

所以,试着从简单的东西开始,一旦它起作用,即使是复杂的东西也会。