используя временную таблицу с NHibernate - PullRequest
0 голосов
/ 17 января 2010

Я пытаюсь сделать то, что кажется расширенным использованием NHibernate с функциями сервера SQL.
Я использую интерфейс NHritnate ICriteria для подкачки, сортировки и фильтрации своих списков просмотра. один из бизнес-объектов - это совокупность элементов из 3 разных таблиц. Для этого в БД я использовал функцию transact-sql, принимающую параметры.
Я использую интерфейс IQuery, возвращаемый session.GetNamedQuery, для вызова функции. но чтобы использовать код подкачки / фильтрации / сортировки, я бы хотел использовать интерфейс ICriteria. для достижения этого я подумал:

  1. Открытие новой транзакции
  2. вызов функции, которая создаст глобальную временную таблицу (вместо возврата результата, как сейчас)
  3. каким-то образом изменить отображение NHibernate, чтобы оно применялось к временной таблице (не уверен, что я могу это сделать, также это должно зависеть от области, в которой я создаю транзакцию ...)
  4. выполнить запрос к новой таблице, используя новое отображение, используя интерфейс ICriteria
  5. Удалить временную таблицу

так много вопросов:

  1. можете ли вы предложить альтернативу?
  2. возможно ли заменить таблицу в отображении NHibernate во время выполнения локально для определенной области кода?
  3. Насколько дорогостоящим будет создание и удаление временной таблицы?

Ответы [ 3 ]

1 голос
/ 11 февраля 2011
1 голос
/ 18 января 2010

Можете ли вы заменить функцию видом? Это представление может объединять 3 таблицы, отображаться с помощью NHibernate и легко разбиваться на страницы / сортироваться / фильтроваться.

0 голосов
/ 11 октября 2018

Я использую табличную переменную внутри запроса Hibernate SQL, используя SQL 2012 Dialect, как показано ниже. В моем сценарии я не мог заставить конкретный параметризованный, разбитый на страницы запрос работать менее чем за 17 секунд, независимо от того, как я сконструировал фильтр. При использовании табличной переменной время захвата страницы N с размером страницы 1000 привело к ответу в секунду.

Вся магия происходит в SQL ниже, чем

  1. создает табличную переменную - declare @temporderstatus table
  2. выбирает строки в табличной переменной - insert into @temporderstatus, отфильтрованные по sql в sqlfilter string
  3. выбирает данные из табличной переменной для возврата в NHibernate , упорядоченный таким образом, что разбиение на страницы возвращает предсказуемый набор результатов - select OrderNum, Customer... from @temporderstatus ORDER BY StatusCodeChangedDate, OrderNum
  4. использует функции подкачки NHibernate для вставки необходимых операторов ROW / OFFSET с использованием диалекта SQL Server 2012 - SetFirstResult((pagination.Page - 1) * pagination.PageSize).SetMaxResults( pagination.PageSize )

В отличие от временной таблицы, табличная переменная очищается после себя, поэтому она идеально подходит для сценариев NHibernate, где у вас есть веб-сервер, который обслуживает разбитые на страницы запросы.

Вот мой код ...

            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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...