【问题标题】:using a temporary table with NHibernate在 NHibernate 中使用临时表
【发布时间】:2010-01-17 12:06:46
【问题描述】:

我正在尝试将 NHibernate 与 sql server 函数一起进行高级使用。
我正在使用 NHibernate 的 ICriteria 接口为我的列表视图提供分页、排序和过滤。 其中一个业务对象是来自 3 个不同表的项目的聚合。 为了在数据库中进行这种聚合,我使用了一个接受参数的 transact-sql 函数。
我正在使用 session.GetNamedQuery 返回的 IQuery 接口来调用该函数。但为了使用分页/过滤/排序代码,我想使用 ICriteria 接口。 为了实现这一点,我考虑过:

  1. 开启新交易
  2. 调用将创建全局临时表的函数(而不是像现在这样返回结果)
  3. 以某种方式更改 NHibernate 映射,使其适用于临时表(不确定我是否可以这样做,这也必须特定于我创建事务的范围...)
  4. 使用 ICriteria 接口使用新映射对新表运行查询
  5. 删除临时表

这么多问题:

  1. 您能推荐一个替代方案吗?
  2. 是否可以在运行时本地替换特定代码范围的 NHibernate 映射中的表?
  3. 生成和处理临时表的成本是多少?

【问题讨论】:

  • 当我不知道在哪里建议替代方案时,我无法建议替代方案。什么是类,什么是表?为您所描述的内容使用临时表听起来很奇怪,但在您使用它的上下文中可能是合乎逻辑的?
  • 我同意 Paco,我认为不需要临时表..

标签: nhibernate tsql temp-tables sql-function


【解决方案1】:

你能用视图替换函数吗?此视图可以聚合 3 个表,由 NHibernate 映射,并且易于分页/排序/过滤。

【讨论】:

  • 我可以这样做,但这会损害性能,因为连接将在 3 个表中的所有行上执行,而我在函数中使用的连接是为特定外键完成的。正如@Paco 所建议的那样,我希望尽快提供更多信息,请原谅我的延迟......谢谢!
【解决方案2】:

我写了一篇博文,展示了如何在这里做到这一点:pagination for performance intensive queries using nhibernate and sql server temporary tables

【讨论】:

    【解决方案3】:

    我使用 SQL 2012 Dialect 在 Hibernate SQL 查询中使用表变量,如下所示。 对于我的场景,无论我如何构建过滤器,我都无法在 17 秒内完成特定的参数化、分页查询。通过使用表变量,抓取页面大小为 1000 的页面 N 的时间导致亚秒级响应。

    所有的魔法都发生在下面的 SQL 中

    1. 创建一个表变量 - declare @temporderstatus table
    2. 将行选择到表变量中 - insert into @temporderstatussqlfilter 字符串中的 sql 过滤
    3. 从表变量中选择数据以返回到 NHibernate 排序以便分页返回可预测的结果集 - select OrderNum, Customer... from @temporderstatus ORDER BY StatusCodeChangedDate, OrderNum
    4. 使用 NHibernate 分页功能使用 SQL Server 2012 方言插入必要的 ROW/OFFSET 语句 - SetFirstResult((pagination.Page - 1) * pagination.PageSize).SetMaxResults( pagination.PageSize )

    与临时表不同,表变量会自行清理,因此它非常适合 NHibernate 场景,其中您有一个正在服务分页请求的 Web 服务器。

    这是我的代码...

                var session = _sessionManager.GetStatelessSession();
                StringBuilder sqlfilter = new StringBuilder(
                    @"FROM Orders o join OrderType ot ON o.OrderType = ot.OrderType where o.StatusDate between :fromDate and :toDate" );
                var mainQuery = session.CreateSQLQuery(
                    $@"declare @temporderstatus table (OrderNum int not null, CustomerID int,  OrderType varchar(16), Status varchar(3), StatusCodeChangedDate datetime, OrderDate datetime, DeliveryDate datetime)
          insert into @temporderstatus
          SELECT o.OrderNum, o.CustomerID, ot.Description AS OrderType, o.StatusCode AS Status, o.StatusCodeChangedDate, o.OrderDate, o.DeliveryDate 
          {sqlfilter}
          select OrderNum, CustomerID, OrderType, Status, StatusCodeChangedDate, OrderDate, DeliveryDate 
          from @temporderstatus  
          ORDER BY StatusCodeChangedDate, OrderNum 
          ");
    
           //construct the count query
           var totalCountQuery = session.CreateSQLQuery($"SELECT COUNT(1) OCount {sqlfilter} ");
                totalCountQuery.AddScalar("OCount", NHibernateUtil.Int32);
                totalCountQuery.SetParameter("fromDate", criteria.fromDate);
                totalCountQuery.SetParameter("toDate", criteria.toDate);
                var totalCountResults = totalCountQuery.UniqueResult<int>();
                pagination.TotalResultCount = totalCountResults;
                if (pagination.TotalResultCount == 0)
                {
                    //no results so don't waste time doing another query
                    return new List<OrderDataDto>();
                }
    
           //finish constructing the main query
                mainQuery.AddEntity(typeof(OrderDataDto));
                mainQuery.SetParameter("fromDate", criteria.fromDate);
                mainQuery.SetParameter("toDate", criteria.toDate);
                var mainQueryResults = mainQuery
                    .SetFirstResult((pagination.Page - 1)*pagination.PageSize).SetMaxResults(pagination.PageSize);
    
                var results = mainQueryResults.List<OrderDataDto>();
                return results;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2011-10-28
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      相关资源
      最近更新 更多