Теория
Задача.
Необходимо отображать и редактировать большой список сущностей. Без пейджинга. Сущности редактируются прямо в списке. Каждая сущность включает в себя "тяжелые" ("долгоиграющие") запросы. Под этими запросами я подразумеваю те запросы, которые отрабатываются достаточно долго, ресурсоемки и результаты которых кешировать или не возможно или же не выгодно. Например включает в себя список картинок, которые хранатся в базе в оригинальном размере и при извлечении преобразуюются в меньший размер. Для отображения картинок используется хендлер (тоесть картинки не сохраняются в файловой срситеме). Таким образом, по условию, сущность которая отображается в качестве элемента списка составная и требует определенного количества внутренних запросов для своего формирования. Кешировать даные результаты, будь то ViewState или Session возможно но ресусроемко.
Варианты Реализации.
Вариант Первый.
Самый первый и классический вариант это использование ListView (или GridView. Я предпочитаю первый вариантб так как это позволяет полностью контролировать выходной HTML). Недостатком использования ListView является то, что при любом событии ListView (будь то перевод элемента в состояние редактирования или отменя редактирования, любой PostBack со сороны ListView) необходимо проводить полный перебинд всего ListView. Тоесть, при отсутствии возможности кеширования результатов выборки, это опять вычитка из базы всех связанных данных для кажого элемента списка , биндинг каждого элемента и тд.
При отображении скажем трехсот элементов , простой перевод одного элемента списка в режим редактирования потребует провести 300 на Х запросов к базе ( где Х - количество внутренних запросов для одного элемента списка). Такой подход будет очень расстравать пользователя, который ожидает мгновенной реакции на такое, как ему кажется, простое действие.
Как вариант, это кешировать данные первоночальной выборки (ViewState или Session), но в любом случае, происходит перебинд всех элементов списка. В случае же, когда на ItemDataBound происходит вычитка всех картинок для сущности и "Тяжелые" операции все равно происходят- это не является оптимальным решением. Все равно медленно... И даже если это исключить, все равно придется при изменении сущности либо перечитывать всю коллекцию, либо изменять закешированную коллекцию. При любых вырантах работы с ListView - происходит перебинд все эелементов списка.
Решением могло бы стать наличие таких возможностей как перебинд и перерендер только того элемента коллекции с которым идет работа. Для перерендера только активного элемента списка ListView решением могло бы быть заключение каждого элемента списка в Update Panel. Но к сожалению ListView имеет различные темплейты для каждого из режимов элемента (отображене, редактирование и тд.) и декларативно обьединить их в одну Update Panel не представляется возможным. В Update Panel мы можем положить только весь ListView целиком. Тоесть получаем те же самые проблемы как и при отсутствии Update Panel.
Задача выкристализовывается - "Биндить и рендерить только то, что изменяем".
Вариант Второй.
Для отображения элемента списка мы создаем User Web Controls. Который представляет собой FormView обернутый в Update Panel. И это позволяет рендерить только тот элемент с которым мы работаем. Так как мы рендерим только один активный элемент, нам нет необходимости биндить другие. Мы биндим только один!
Производительность.
Опыты показали, что использованние ListView для первично отображения данных (списка сущностей) дает более быстрые результаты, нежели динамическое добавление User Web Controls для тех же целей. Но дальнейшее использование User Web Controls для редактирования сущности в списке дает лучшую скорость реакции. Я бы скадзал - значительно лучшую ( Так как выборка и биндинг производится только для одной, текущей сущности). Если же отключить ViewState для контролов отображающие статические данные - то производитьельность увеличится как для первого так и для второго подходов.
Вывод.
Использование ListView + кеширование данных выборки (при условии отсутствия некешируемых элементов и долгоиграющих запросов для наполнения каждого элемента списка) удобнее, проще и быстрее нежели динамическое добавление User Web Controls.
НО! Если возникает ситуация, когда для наполнения каждой сущности используются некешируеммые элементы и долгоиграющие запросы тот выгоднее и быстрее использовать динамически добавляемые User Web Controls
Практика
Структура проекта
Комментариев нет:
Отправить комментарий