суббота, 8 марта 2014 г.

Как изменить поле IDENTITY в MSSQL

По умолчанию вы не можете ничего делать с полем, заданным как IDENTITY, при добавлении записей в БД оно автоматически устанавливается сервером и больше никогда не меняется так что, ели создать вот такую таблицу и попытаться добавить в нее ряд явно задав значение столбца ID:

CREATE TABLE [dbo].[identity_test](
 [id] [int] IDENTITY(1,1) NOT NULL,
 [name] [nvarchar](50) NOT NULL
) 

insert into identity_test values (1,'testname2');

То мы получим вот такую ошибку:
Msg 8101, Level 16, State 1, Line 1
An explicit value for the identity column in table 'identity_test' can only be specified when a column list is used and IDENTITY_INSERT is ON.



пятница, 7 марта 2014 г.

Как использовать свои таблицы стилей в веб-частях Sharepoint

Если у вас когда-нибудь возникнет необходимость использовать в веб-части в SharePoint какие-то свои таблицы стилей, то сделать можно так:

1) Вначале добавьте в проект папку Layouts. У меня этот вариант недоступен, потому что папка уже добавлена.



четверг, 6 марта 2014 г.

Немного про обработку исключений

А конкретно про оператор throw и одну особенность его вызова в блоке catch о которой не все знают и даже в MSDN о ней написано чуть более чем ничего. Вот цитата:

The throw statement can be used without an argument, but only if the throw statement is contained within a catch block. In that situation, the throw statement re-throws the error caught by the enclosing catch statement. When an argument is provided, the throw statement throws the value of exception.

На самом деле, основная разница в вызове throw с аргументом и без - в сохранении стека вызова.

Проиллюстрировать эту разницу можно вот такой простой программкой:


среда, 5 марта 2014 г.

Как сделать фильтр в GridView

Если вдруг вам потребовалось сделать фильтрацию данных в стандартном ASP.NET контроле GridView, то не спешите расстраиваться и смотреть в сторону всякий телериков. Все можно сделать своими руками. Получится примерно так:


Итак, вот что нужно сделать для того, чтобы получить такой результат. Во первых, создать GridView и объявить колонку, по которой будете фильтровать как TemplateField.

<asp:gridview autogeneratecolumns="False" cellpadding="4" forecolor="#333333" gridlines="None" id="ListGrid" runat="server">
                <columns>

                    <asp:boundfield datafield="Name" headertext="Название">
                    <asp:templatefield headertext="Тип Записи">
                        <headertemplate>
                            Тип Записи:
                            <asp:dropdownlist autopostback="True" id="typeSelect" onselectedindexchanged="typeSelect_SelectedIndexChanged" runat="server">
                                    <asp:listitem text="Все" value="All"></asp:listitem>
                                    <asp:listitem text="Автомобили" value="1"></asp:listitem>
                                    <asp:listitem text="Самолеты" value="2"></asp:listitem>
                                    <asp:listitem text="Мотоциклы" value="3"></asp:listitem>
                            </asp:dropdownlist>
                        </headertemplate>
                        <itemtemplate>
                                 <#Eval("Type")>              
                        </itemtemplate>
                        <itemstyle horizontalalign="Center">
                    </itemstyle></asp:templatefield>                                      
                  </asp:boundfield>
                </columns>
 </asp:gridview>

Для простоты будем связывать нашу таблицу со списком вот таких вот элементов:
    public class Machine
    {
        public string Name { get; set; }
        public string Type { get; set; }

        public Machine(string _name, string _type)
        {
            Name = _name;
            Type = _type;
        }
    }


Распродажа авиабилетов от S7 и Аэрофлота

Только что наткнулся на интересное предложение от S7. Можно слетать в некоторые европейские города за вполне вменяемые 10-13 тысяч за билет туда-обратно.  Правда лететь надо до конца мая.
В общем, полные условия и бронирование по ссылке: http://www.s7.ru/home/offers/vesennyaya-rasprodazha-aviabiletov?utm_source=odnoklassniki&utm_medium=sm_post&utm_campaign=sale_spring

UPD: Вспомнил, что Аэрофлот тоже распродает билетики. Правда покупать надо до 6 марта включительно, но зато выбор побогаче. Вот: http://www.aeroflot.ru/sale/?utm_source=aeroflot.link.subscribe.ru&utm_medium=referral&utm_campaign=esale032014&utm_content=sale03032014


Как сохранить поле предшественников задачи в SharePoint

В SharePoint есть такой тип, как задача (task) на базе которых можно построить много всяких интересных и полезных вещей, включая вполне полноценный корпоративный планировщик задач. Единственная вещь, которая не совсем очевидна при работе с задачами - это как программно создать или изменить список предшествующих задач. На самом деле, ничего особо сложного в этом нет.
Вот так, например, можно создать задачку с определенным предшественником:

        protected void CreateChildTask(SPListItem parent)
        {
            var web = SPContext.Current.Web;
            var list = web.Lists["MyTasks"];
            SPListItem item = list.Items.Add();

            item[SPBuiltInFieldId.Title] = "Новая задача";
            SPFieldLookupValueCollection predecessorItems = new SPFieldLookupValueCollection();
            SPFieldLookupValue predecessor = new SPFieldLookupValue(parent.ID, parent.Title);
            predecessorItems.Add(predecessor);
            item[SPBuiltInFieldId.Predecessors] = predecessorItems.ToString();
            item.Update();
        }

А вот так можно добавить предшественника:

        protected void UpdateChildTask(SPListItem parent, SPListItem task)
        {
            SPFieldLookupValueCollection predecessorItems = new SPFieldLookupValueCollection(task[SPBuiltInFieldId.Predecessors].ToString());
            SPFieldLookupValue predecessor = new SPFieldLookupValue(parent.ID, parent.Title);
            predecessorItems.Add(predecessor);
            task[SPBuiltInFieldId.Predecessors] = predecessorItems.ToString();
            task.Update();
        }


Так что, кроме не очевидного шаманства с преобразованием строки в коллекцию и обратно, ничего сложного нет.


вторник, 4 марта 2014 г.

Про css свойство display

Только что столкнулся с не очевидной, по крайней мере для меня, особенностью интерпретации свойства display разными браузерами. Нужно было мне сделать табличку со сворачиваемыми рядами. Вот, типа такую (это скриншот с Internet Explorer):


Отображение и скрытие рядов делается в частности вот такой нехитрой конструкцией:

    
  $(this).css('display', 'none');

или

  $(this).css('display', 'block');

В результате чего в Chrome получалось вот такая фигня:

В общем, я около часа потратил на поиски проблемы. А в итоге решил заглянуть в документацию. Оказалось, что в случае, если я убираю или добавляю ряд таблицы, то, согласно новым спецификациям, нужно писать:
    
  $(this).css('display', 'table-row');

С таким стилем во всех браузерах все отображается одинаково правильно.


Мой новый старый блог

Ровно год назад я закрыл свой предыдущий блог и решил что больше писать не буду. Ну так, если только в фейсбучек иногда. Тогда же под раздачу попал и мой второй проект - блог о программировании, в который я, правда, практически не писал.
А вчера я с чего-то вдруг решил снова создать блог. На этот раз блог будет один. Писать часто и много не обещаю. Но, писать буду обо всем.
В основном, думаю, о программировании, так как всякого интересного накопилось много. Но также и о путеществиях, о еде, о напитках, да и просто мысли разные писать. Так что, заходите ;)


Получение списка файлов в директории LINQ-style

Небольшой хак, смысл которого, разве что, в красоте кода, ну и небольшом удобстве и совсем незначительной экономии памяти. Например, нам нужно получить имена всех текстовых файлов в какой-то директории. Олдскульный способ сделать это примерно такой:

DirectoryInfo di = new DirectoryInfo(folderPath);

            List filenames;
            FileInfo[] allFiles = di.GetFiles("*.txt");
            foreach (FileInfo singleFile in allFiles)
            {
                filenames.Add(singleFile.Name);
            }

А так как DirectoryInfo.GetFiles возвращает массив, то мы можем использовать функцию IEnumerable.Select. Примерно так:

DirectoryInfo di = new DirectoryInfo(folderPath);

// Получаем список .TXT файлов
List filenames = di.GetFiles("*.txt")
                        .Select(file => file.Name).ToList();