25 мая 2009 г.

Пора начинать копилку...

Получил сегодня письмо следующего содержания (орфография, лексика и т.п. сохранены):

дорогой глупый тимофей! я тебя ненавижу раз уж больше я тебя не увижу, так как тебе это неинтересно, можно больше не притворяться. это я писала оскорбительные каменты в твой блог конечно ты являешься засушенным рациональным сухарем, поэтому до тебя не допрет твоя личная ничтожность мечтаю тебе сказать: ИЛИ НА ХУЙ хоть ты по-любому победишь мой спик-баттл, я скажу все!сказать в лицо было невозможно, потому что на него противно смотреть! ты мудоеб! вот тебе мат, раз ты его не терпишь, целомудренно не куришь и не пьешь! у тебя ебанутые шутки. мы не знали как и реагировать-то на них! ты один из самых неприятных мне людей! неясно только как все остальные не видят этого. видимо полости в их головах неизлечимы При случае надо будет заняться анализом текста...

Пока не настолько разнообразно, как у Дмиха, но видимо всё еще впереди - надо начинать копилку...

Самое интересное, что с человеком, который мне это написал я не имел никаких отношений, ну просто вообще никаких - находились в одном коллективе: привет-пока и ничего больше. И ведь не лень было написать мне это в личку, на стенке и в блог...

13 мая 2009 г.

gotdotnet.ru, Обратная связь скоро будет...

На www.gotdotnet.ru нажал на ссылку "Обратная связь", в ответ увидел: Sorry, site is temporary unavailable. Approximate time of launch is 25 Dec 2008 21:00. Интересно, а декабрь прошлого года скоро наступит?

12 мая 2009 г.

Не видно содержимого System.Windows.Forms.Clipboard

Проблема

При обращении к Clipboard.GetText() возвращается null, равно как и к остальным методам, хотя данные в буфере обмена есть.

Решение

Нужно добавить атрибут STAThread к входной точке программы:[STAThread]
static void Main(string[] args)

Генерирование LINQ-запросов в runtime

Большое удобство составления запросов в строку в том, что можно динамически добавлять условия и собственно генерировать логику отбора в рантайме, так можно поступать и с LINQ, причем дополнительные условия можно накладывать не в виде вызова методов, а так же – декларативно.

При этом для уточнения условий отбора нужно просто выполнить запрос к запросу. Благодаря тому, что запрос выполняется не сразу, а в момент обращения к его результату – будет выполнено уточнение начального запроса. Если при этом тип возвращаемого результата остается тем же (выбираем тот же тип данных), то запрос можно присвоить той же переменной.

Для примера создадим в MS-SQL таблицу Test со столбцом Value типа int и ts типа TimeStamp (чтобы полей было всё же больше, чем те, с которыми нужно работать). Нам нужно выбрать из этой таблицы все четные значения больше 5, отсортированные по возрастанию.

Это можно написать в обычном запросе вот так:

var q = from item in DB.tests
         where item.value % 2 == 0 && item.value > 5
         orderby item.value
         select item.value;
При этом мы получим IEnumerable<int> и в базу отправится запрос

exec sp_executesql N'SELECT [t0].[value] FROM [dbo].[test] AS [t0] WHERE (([t0].[value] % @p0) = @p1) AND ([t0].[value] > @p2) ORDER BY [t0].[value]',N'@p0 int,@p1 int,@p2 int',@p0=2,@p1=0,@p2=5

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

string query = "SELECT value FROM Test WHERE (1=1)";
query += " AND (Test.Value % 2 = 0@)";
if (flag)
    query += " AND (Test.Value > 5)";

query += " ORDER BY Test.Value";

Такую же гибкость предоставляет и LINQ, при осуществлении запроса к запросу. Сделаем тот же самый запрос на LINQ в несколько шагов:

1. Выберем базовый набор элементов с которыми хотим работать, пусть это будут вся таблица Test

var q = from item in DB.tests
        select item;

Это преобразуется в запрос

SELECT [t0].[value], [t0].[ts] FROM [dbo].[test] AS [t0]

2. Но поскольку к результатам запроса мы еще не обращаемся, то к БД он не отправлен, уточняем наш запрос:

q = from item in q
    where item.value % 2 == 0
    select item;

Мы добавили условие четности и запрос соответственно уточнился:

SELECT [t0].[value], [t0].[ts] FROM [dbo].[test] AS [t0] WHERE ([t0].[value] % @p0) = @p1

Теперь уточним запрос, т.к. мы хотим работать только со столбцом value – выбираем его.

var nums = from num in q
           select num.value;

3. Запрос уточняется до

SELECT [t0].[value] FROM [dbo].[test] AS [t0]

т.е. если запросить данные сейчас, то выберется уже только один столбец, а не вся таблица. Но суть даже не в этом – раз мы выбрали только один целочисленный столбец мы теперь и работаем с ним просто как с коллекцией целых чилел. Обратите внимание – у нас поменялся тип результата – вместо всех столбцов мы выбираем только один, поэтому нам нужна новая переменная (используется новый тип данных)

4. Выбираем из них четные:

nums = from num in nums
       where num % 2 == 0
       select num;

и запрос снова уточняется:

SELECT [t0].[value] FROM [dbo].[test] AS [t0] WHERE ([t0].[value] % @p0) = @p1

Здесь и дальше мы уже работает только с коллекцией int’ов, так что используем ту же самую переменную.

5. Теперь уточняем запрос в зависимости от какого-то нашего условия:

if (flag)
    nums = from num in nums
           where num > 5
           select num;

У меня влаг выставлен в true, поэтому условие уточняется:

SELECT [t0].[value] FROM [dbo].[test] AS [t0] WHERE ([t0].[value] > @p0) AND (([t0].[value] % @p1) = @p2)

6. Сортируем полученный результат:

nums = from num in nums
       orderby num
       select num;

Запрос еще раз уточняется:

SELECT [t0].[value] FROM [dbo].[test] AS [t0] WHERE ([t0].[value] > @p0) AND (([t0].[value] % @p1) = @p2) ORDER BY [t0].[value]

И наконец обращаемся к результату:

foreach (var num in nums)
    Console.WriteLine(num);

Согласно SQL Profiler’у туда пришел запрос:

exec sp_executesql N'SELECT [t0].[value] FROM [dbo].[test] AS [t0] WHERE ([t0].[value] > @p0) AND (([t0].[value] % @p1) = @p2) ORDER BY [t0].[value]',N'@p0 int,@p1 int,@p2 int',@p0=5,@p1=2,@p2=0

Запрос совершенно эквивалентные, отличаются только порядком условий в AND.

В чем плюсы такого подхода?

1. Мы работает с типизированной коллекцией того что нам нужно (контроль опечаток на стадии компиляции, автодополнения и т.п.)

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

3. Каждое уточнение выглядит человеко-читабельно: из уже выбраного выбираем то, что соответствует новому условию или условиям (можно доабвлять произвольное количество условий за раз).

4. Не смотря на такую конструкцию - запрос к запросу - реально в базу отправляется только один результирующий запрос, учитывающий сразу все условия, что собственно нам и нужно.

5. Можно писать условия отбора в человеческом порядке на человеческом языке, так что это потом будет просто понять и исправить (пример приведен ниже)

P.S. После написания поста стало интересно попробовать – а что если нам нужно будет выбрать из той же таблицы четные числа больше 5, но только среди чисел, которые идут с 5-го по 25-й если их отсортировать. Т.е. при переводе на русский это получается так:

Отсортировать числа в столбце value по возрастанию, взять из них элементы с 5-го по 25-й включительно и среди них выбрать четные числа больше 5.

Написал такой кусок кода:

var nums = from item in DB.tests
        orderby item.value
        select item.value;

nums = nums.Skip(4).Take(21);

nums = from num in nums
       where num % 2 == 0 && num > 5
       select num;

foreach (var num in nums)
    Console.WriteLine(num);

из чего сгенерировался запрос:

exec sp_executesql N'SELECT [t2].[value] FROM ( SELECT [t1].[value], [t1].[ROW_NUMBER] FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [t0].[value]) AS [ROW_NUMBER], [t0].[value] FROM [dbo].[test] AS [t0] ) AS [t1] WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1 ) AS [t2] WHERE (([t2].[value] % @p2) = @p3) AND ([t2].[value] > @p4) ORDER BY [t2].[ROW_NUMBER]',N'@p0 int,@p1 int,@p2 int,@p3 int,@p4 int',@p0=4,@p1=21,@p2=2,@p3=0,@p4=5

Вот фиг бы я такой запрос вручную написал, да если и написал бы, то не слишком он читабельный и правибельный, в LINQ как-то проще.

11 мая 2009 г.

Windows 7 RC... Глюк с изменением размера панели задач

Как воспроизвести: 1. Ставим панель задач слева или сверху (снизу и справа глюк не проявляется) 2. Растягиваем ее 3. Возвращаем к нормальному размеру чтобы убрать остаток этой панели нужно или выйти-войти в рабочий стол заново или перетащить панель задач вниз(вправо) и потом вернуть на место. P.S. Что интересно - глюк у панели задач слева в висте не новость, в Windows XP SP2 например если выбрана синяя XP-шная тема оформления и панель задач висит слева, то при каждой перезагрузке её ширина уменьшалась на один значек трея.

7 мая 2009 г.

Самый быстрый способ разориться

Понравился текст на баннере: Есть три способа разориться: самый быстрый - скачки, самый приятный - женщины, самый надежный - сельское хозяйство. Уильям Питт, граф Амхерст

Премьера спектакля "Самоубийца"

Тграгикомедия по пьесе Николая Эрдмана "Самоубийца". Действие происходит в начале 20-го века, сразу после революции. В этой пьесе показывается жизнь обычного человека из массы, которого каждый пытается использовать в своих интересах даже в момент, когда он кончает жизнь. Спектакль будет проходить в ДК "Магистраль" (так же известен как ЯРЗ), около московского вокзала в воскресенье, 17 мая 2009 года, стоимость билета 60 рублей. В ролях: Андрей Охапкин - Подсекальников Семен Семенович Анна Постнова - Мария Лукьяновна (его жена) Наталия Паршина - Серафима Ильинична (его тёща). Николай Секретарёв - Александр Петрович Калабушкин (их сосед). Наталья Ефимова - Маргарита Ивановна Пересветова, бабка. Тимофей Кулин - Аристарх Доминикович Гранд-Скубик. Сергей Штефан - Никифор Арсентьевич Пугачев (мясник), алкаш. Наталья Серова - Клеопатра Максимовна, бабка. Александр Новиков - Отец Елпидий (священник), алкаш. Анастасия Воронина - Виктор Викторович (писатель), Генриетта Степановна. Светлана Крашенинникова - Егорушка (Егор Тимофеевич), немая девушка, помощница Генриетты Степановны.

4 мая 2009 г.

Москва, москва... Или где можно ездить на красный...

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

Сигналка или нервы

Сегодня ночью (около 2.30) впервые сработала сигналка на машине, я естественно вскочил как ошпаренный, пошел к окну смотреть что случилось… ничего не увидел – может испугались сигналки и убежали… через несколько минут какой-то парень мимо машины прошел… и больше ни души…

Потом полночи еще уснуть не мог от этого стрессового вскакивания и с мыслями – может лучше без сигналки (и возможно просто машину в гараж поставить), чем так себе нервы насиловать…

3 мая 2009 г.

Windows 7 RC... Установка

К сожалению обновление с беты до RC не поддерживается, поэтому ставил заново. Установка Releace Candidate прошла намного быстрее, чем беты - если бета ставилась час с лишним (по ощущениям - успел позастракать, сходить в душ, потом еще полчаса ждал), то RC установилась минут за 20. Запускается еще быстрее, выглядит еще красивее. Одно недоумение - почему убрали картинки пользователей из висты... Мне оч. нравились шахматы для рабочего логина и что-то такое милое (не помню что) для личных нужд. Что-то милое есть - собачка, а вот шахмат больше нету... придется выцеплять из висты.

2 мая 2009 г.

Windows 7 Beta... WiFi...

Не видит WiFi-сети на моем буке.
Точнее сначала видела, потом перестала. Возможно, что из-за того что проводную сетку назвал так же как WiFi, но это только предположение.
Качаю Windows 7 RC x86