четверг, 13 января 2011 г.

ListView , Paging ( DataPager) и как обнулить индекс страницы для пейджинга.

Для того чтобы заполучить в свое распоряжение разбивку на страницы ( Paging ) в ListView необходимо использовать контрол DataPager. DataPager может быть расподожен  как пределах ListView в LayoutTemplate так и за пределами ListView . Но тогда для DataPager необходимо установить свойство PagedControlID которое будет указывать на наш ListView. Ниже два примера использования.

Внутри ListView
<asp:ListView  ID="ListView1"  runat="server">
 <LayoutTemplate>
  <ul>
   <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
  </ul>
  <asp:DataPager ID="Pager1" runat="server" PageSize="40">
   <Fields>
    <asp:NumericPagerField />
   </Fields>
  </asp:DataPager>
      
 </LayoutTemplate>
 <ItemTemplate>
  <li>
   <asp:Literal ID="litContent" runat="server"/>
  </li>
 </ItemTemplate>
</asp:ListView>

За Пределами ListView
<asp:ListView  ID="ListView1"  runat="server">
 <LayoutTemplate>
  <ul>
   <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
  </ul>
 </LayoutTemplate>
 <ItemTemplate>
  <li>
   <asp:Literal ID="litContent" runat="server"/>
  </li>
 </ItemTemplate>
</asp:ListView>
<asp:DataPager ID="Pager1" PagedControlID="ListView1" runat="server" PageSize="40">
   <Fields>
    <asp:NumericPagerField />
   </Fields>
</asp:DataPager>


Я предпочитаю использовать  DataPager за пределами ListView. Все нижеописаноое будет относиться к этому варианту использования.

Итак дальше... Предоложим у нас имеется  некая поисковая форма и кнопка "Искать". Пользователь вводит данные  в форму и нажимает кнопку.  По нажатию происходит выборка данных и наполнение ListView

А теперь ситуация... Допустим по условиям выборки в  ListView попадает 100 строк. Наш пейджинг ( с установкой в 40 записей ) разобьет все это дело на три страницы. Пользователь переходит на третью страницу, вводит новые параметры для поиска и опять нажимает "Искать". Теперь наша выборка содержит только 10 строк. Производим наполение ListView и видим только форму поиска и пейджинг - а самого ListView нет, хотя мы точно знаем, что данными он был наполнен.

Причина в том DataPager не был обнулен. Тоесть он по пережднему показывает на третью страницу, но ее уже нет. Вот и возникат конфликт.
Для решения этой проблемы , в нашем случае,  в обработчике щелчка кноки нужно вызвать метод SetPageProperties нашего датапейджера.

Pager1.SetPageProperties(0, 40, True)

где первый параметр - стартовый индекс (индекмирование с 0), а второй - количество строк на странице.
Все. Теперь после каждого щелчка по кнопке  "Искать" пользователь будет оказываться на первой странице  нашего ListView, отображающего результаты поиска.


вторник, 4 января 2011 г.

Оптимизация отображения больших списков сущностей

Обнаружил в приложении определенную функциональность. Один из так называемых "ASAP" блоков. Суть в следующем - отображение больших  списков сущностей ( А - сущность) и информации из  сущностей связанных с сущностью A по некоторым критериям(сущности Б, С и Д). Сущности Б,С и Д связаны с сущностью А по определенным бизнес правилам.  В результате время отображения полного списка из тысячи сущностей А и дополнительной информации из сущностей Б,С и Д составляло 4.5 минуты.
Даный результат достигался благодаря слудующему решению.
  1. Выбирался коллекция из сущностей A
  2. Полученная коллекция в цикле обрабатывалась и для каждой сущности A брались соответствующие сущности Б,С и Д. Даже при условии что на получение сущности Б,С или Д тратилось одно обращение к базе - получаем три тысячи обращений к базе.
  3. три тысячи одно обращение к базе - вот вам и четыре с половиной минуты.
Как вариант, следущее решение проблемы. Данное решение показало результат в 4 секунды. (Неплохо против четырех с половиной минут!)
  1. Выбирать коллекцию из сущностей A
  2. Выбирать коллекцию из всех сущностей Б которые связанны с сущностями  из коллекции А.
  3. Выбирать коллекцию из всех сущностей С которые связанны с сущностями  из коллекции А
  4. Выбирать коллекцию из всех сущностей Д которые связанны с сущностями  из коллекции А
  5. Для каждого элемента из коллекции А выбирать соответствующие сущности Б,С и Д из уже наполненных коллекций посредством "LinQ to Object". 
  6. 4 запроса к базе всместо 3001 - 4 секунды вместо 4,5 минут.