简体   繁体   English

将postgres查询重写为NHibernate

[英]Rewriting postgres query to NHibernate

Please can you advise how I can write the following using NHibernate's QueryOver<>() Query<>() or other NHibernate method that will not involve me rewriting this (and numerous other similar queries) when switching DB provider? 请您告知我如何使用NHibernate的QueryOver <>()Query <>()或其他NHibernate方法编写以下内容,这些方法在切换数据库提供程序时不会涉及我重写此代码(以及许多其他类似的查询)吗?

The subqueries with multiple table joins are making this a pain for me to translate with my limited exposure of 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();

Thanks 谢谢

I would heavily doubt that you'll ever recieve answer for your giant SQL Query - and its conversion. 我非常怀疑您是否会收到针对您的巨型SQL查询及其转换的答案。 Meanwhile, I would like to point out some differences in approach/thinking when using NHibernate. 同时,我想指出使用NHibernate时在方法/思想上的一些差异。

  • Use entities first. 首先使用实体​​。 Define your model, the business domain model with Users , Topics , Boards . 使用UsersTopicsBoards定义您的模型,业务领域模型。
  • Spend some time to understand the lazy loading. 花一些时间来了解延迟加载。 Lot of data could be recieved by simple query to get User(s) , and then nagivating to his boards, topics... All data needed will be loaded in separted SQL statements, but without complex querying. 可以通过简单的查询来获取大量数据,以获取User(s) ,然后将其导航到其板子,主题...所有需要的数据将被加载到分离的SQL语句中,但无需复杂的查询。
  • Do check the advantages fo batch-loading , which is a technique how to avoid 1+N SELECT issue. 请检查批处理加载的优点,这是一种避免1 + N SELECT问题的技术。 It is really working well and has surprisingly large effect on amount of issued SQL statements. 它确实运行良好,并且对发出的SQL语句的数量产生了惊人的巨大影响。
  • DO NOT WORRY to use native SQL to recieve "..." data required by users (replace dots with words like crazy, unbelievable, complex) . 不必担心使用本机SQL来接收用户所需的“ ...”数据(将点替换为疯狂,令人难以置信,复杂的单词) NHibernate is ORM at first place. NHibernate首先是ORM。 It does great job for all CRUD operations related to Business object model. 对于与业务对象模型相关的所有CRUD操作,它都做得很好。 Any "SP like selects" are supported but indirectly... via CreateSQLQuery 支持任何“ SP之类的选择”,但通过CreateSQLQuery间接...

So, try to start with simple stuff and once that is working, even the complex one will. 因此,尝试从简单的东西开始,一旦可行,即使是复杂的东西也可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM