вторник, 29 ноября 2011 г.

I FADE...

I'm plagued by the silence
You brought upon me
Suffering in the desolate laps of time
Tearing the flesh from my bones
Endless eternity awaits
Smothered by life
Emptiness takes hold
Eternity shines brighter
Than ever before
I'm lost with despair
No one's left to care
Alone, abandoned
To die by myself...
Endless eternity awaits

вторник, 22 ноября 2011 г.

JavaScript ошибка "zofnhot=ofnh.offsetTop*zm" при генерации отчета в Microsoft Report Viewer

Вобщем  поймал я эту хрень , иначе не назовешь, при генерации простого рапорточка средствами Microsoft Report Viewer... Данные простые, таблица простая - и эта ошибка. Вообщем я не вникал почему она возникает, очень похоже на то что репортвьювер лагает где-то с определениями размеров... Проблема оказалась в повторяющихся хидерах/футерах, в настройках таблицы в рдлс файле.. убрал галочки - проблемы исчезли.

вторник, 30 августа 2011 г.

AS in C#

namespace ConsoleApplication1
{     
    class Program
    {
        static void Main(string[] args)
        {
            Object st1 = new ST1();
            string S1 = String.Empty;
            S1 = (String)st1;
            S1 = st1 is String ? (String)st1 : null;
            S1 = st1 as String;
        }
    }
    //Empty class
    public class ST1 { }
}

S1 = (String)st1;  - при отладке получим ошибку : "Unable to cast object of type 'ST1' to type 'System.String'."

S1 = st1 is String ? (String)st1 : null; - Сработает корректно.

S1 = st1 as String; - Сработает корректно.

S1 = st1 as String - всего лишь укороченный синтаксис для S1 = st1 is String ? (String)st1 : null;



пятница, 20 мая 2011 г.

SQL error: "Too many parameters were provided in this RPC request" или ошибка 2100 парметров в SQL запросе

Причиной этой ошибки является ограничение количества параметров который можно передать в SQL команду. Обычно данная ситуция возникает когда нужно вычитать список сущностей по идентификатору.
SELECT *  FROM table WHERE Id = idValue1 OR Id = idValue2 OR Id = idValue3 ...OR Id = idValue3000
или
SELECT *  FROM table WHERE Id IN (idValue1,idValue2,idValue3...idValue3000)

Возникает  эта ситуация конечно не часто,  но и она имеет место быть. Заявления вроде "Да как вы вообще допустили появления таких запрсов в системе!" - не принимаются. Различные системы, различные архитектурные ограничения...  И  вот, пожалуйста,  все упирается в необходимость вычитать из базы 3000 сущностей по дентификатору...

Задача.
Имеется исходная коллекция  идентификатов сущностей А. Коллекция может содежать больше 2100 элементов ( а може и меньше, но это не важно. Как и не важно то,  как и откуда эта коллекция взялась. Она есть.). Необходимо вычитать из базы все сущности А, айдишники которых присутствуют в коллекции идентификаторов . Порядок вычитанных сущностей должен совпадать с порядком следования элементов в исходной коллекции идентификаторов.

Решение.
Продолжение следует...

Вычитка коллекции по частям

Задача.
Есть типизированная коллекция. Необходимо производить последовательную вычитку коллекции по частям. Например, коллекция из 10 элементов. Последовательно вычитать первые 4 элемента, вторые 4 элемента и тд.

Решение.  
Sub Main()
  Dim l As New List(Of Integer)
  l.Add(1) : l.Add(2) : l.Add(3) : l.Add(4) : l.Add(5) : l.Add(6) : l.Add(7) : l.Add(8) : l.Add(9) : l.Add(10)
  Dim total As Integer = l.Count
  Dim sizeOfPage As Integer = 4
  Dim qantityOfPages As Integer = CInt(Math.Truncate(total / sizeOfPage))
    For i As Integer = 0 To qantityOfPages
      Dim startPos As Integer = i * sizeOfPage
      Dim innerList As List(Of Integer) = l.Skip(startPos).Take(sizeOfPage).ToList
      For Each ed In innerList
        Console.WriteLine(ed.ToString)
      Next
      Console.WriteLine()
    Next
  Console.ReadLine()
End Sub

Ниже аналогичное решение, но полностью на foreach ... next и if ... end if

Sub Main()
  Dim l As New List(Of Integer)
  l.Add(1) : l.Add(2) : l.Add(3) : l.Add(4) : l.Add(5) : l.Add(6) : l.Add(7) : l.Add(8) : l.Add(9) : l.Add(10)
  Dim total As Integer = l.Count
  Dim sizeOfPage As Integer = 4
  Dim qantityOfPages As Integer = CInt(Math.Truncate(total / sizeOfPage))
    For i As Integer = 0 To qantityOfPages
      Dim startPos As Integer = i * sizeOfPage
      Dim endPos As Integer = startPos + sizeOfPage
        For ed As Integer = startPos To endPos - 1
          If ed < l.Count Then
            Console.WriteLine(l.Item(ed).ToString)
          Else
            Exit For
          End If
        Next
        Console.WriteLine()
    Next
  Console.ReadLine()
End Sub

в обоих случаях получаем следущее:

четверг, 19 мая 2011 г.

TextBox и Еnter

:)
Присутствовала некая форма. В этой форме присутсвовало некое текстовое поле - якобы "MultiLine"..  визуально все нормально - выглядит как обычный "MultiLine" (в том смысле что "высокое и широкое" ,  ну обычная TextArea...)   Но почему то при нажатии в текстовом поле Еnter на форме срабатывал постебек. Вместо того чтобы создавать новую строку в текстовом поле - форма отправлялась на сервер...
Первая мысль - блокировать реакцию на Enter... заблокировал . 
Все отлично  - Enter блокируется. Но и  и новая строчка не создается...
Что за фигня...
В других то местах такой проблемы даже и не возникало...
Уже думаю писать более хитрый джавскрипт сценарий. И тут вижу - о чудо!
Текстовому полю размеры указаны как для могосторочного, но блин параметр TextMode="MultiLine" отсутствует. Отсюда и  все проблемы. Устновил TextMode="MultiLine" - все проблемы прошли, и никакя блокировка не понадобилась. На Enter производится создание строчки и никаких постбеков.
Мораль - не копипастить бездумно.  

четверг, 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 минут.