вторник, 12 августа 2008 г.

Короткий синтаксис ADO .NET (часть I)

Короткий синтаксис ADO .NET (часть II)
Короткий синтаксис ADO .NET (часть III)
Короткий синтаксис ADO .NET (часть IV)

Да, есть такая технология, пока. Можно даже сказать была, или почти была. Но ADO .NET еще поживет какое-то время. Не хотелось бы обсуждать недостатки этого динозавра в сравнении с LINQ to SQL или Entity Framework, либо ORM подходами. Это не тема данного поста.

Здесь лишь примем факт, что ADO .NET еще пока актуально, хоть и сильно сдает позиции. На этой технологии уже много что написано, и еще пишется, и кое-что будет написано. Хочу обратить внимание, что несмотря на повсеместное засилье ADO в среде .NET разработчиков (до последнего времени), пользоваться ADO в чистом виде довольно неудобно, громоздко. Многие вероятно видали код, сгенерированный дизайнером для DbAdapter-ов, DbCommand и их параметров... А про кол-во манипуляций, необходимых для выполнения запроса и закрытия всех щелей за собой для очистки совести, есть целая история.

История о том, как я проходил собеседование в одну контору на позицию удаленного разработчика. Надо заметить, что вакансия была с заманчивой почасовой оплатой, соразмерной ставке freelancer-а. Интервьюера в большей степени интересовали навыки работы с WinForms и ADO .NET. На вопросы о WinForms я довольно резво ответил (как мне показалось), но с ADO - поплавал: Меня попросили набросать код для чтения каких-либо данных из таблицы БД в DataTable прямо в ICQ. Я что-то быстро набросал и отправил набросок. На что последовал ответ: "Ваш код работать не будет!". Это меня довольно сильно смутило. Я смотрел на этот код и не мог понять, что же в нем не так. Когда я его вставил в Visual Studio и попробовал выполнить, меня озарило: я забыл открыть DbConnection. О чем и поведал интервьюеру.

Заверения о том, что я обычно тестирую свой код и то что такие ляпы не выходят из под моего пера в продакшн, не подействовали на собеседника. Но и сразу отказ я не получил. Мне было позволено задать пару наводящих вопросов и подождать до того, как со мной свяжутся. За пару наводящих вопросов выяснилось, что работа, мягко говоря, не фантан: имеется 250 (или около того) набросков форм, кои надо выполнить в WinForms и сваять для них запросы к 250-ти таблицам. Никакого творчества, инициативы, рефакторинга, тестирования не подразумевалось. Нужно было выдать bug free код как можно быстрее и сделать это как можно ближе к способам, описываемым в MSDN (M$ way).

Понятно, что заклинание использования ADO должно было отскакивать от кандидата как "Отче наш" от послушника в монастыре! Я рад, что мне не предложили эту работу. Я застрелился бы наверное на 10-ой форме. Однако, оправдывает мою забывчивость лишь то, что я не один год работал со своим заклинанием, которое в работе с ADO было на порядок удобнее, чем то что предлагал MSDN. А сейчас мои заклы (заклинания) стали еще удобнее. Именно о том, как может быть удобно с ADO .NET, будет мой пост (может пару или тройку, как попрет).

Попробую перечислить действия, необходимые для выполнения запроса и уборки за собой в общем случае для типа команды ExecuteReader:
  1. Создать DbConnection. Вообще его можно создать обратившись к конструктору, например, SqlConnection. Но в .NET 2.0 появился более правильный путь (через DbProviderFactories, что требует дополнительных манипуляций);
  2. Указать ConnectionString;
  3. Создать DbCommand. Мы можем создать ее через конструктор, либо попросить это сделать connection;
  4. Указать текст команды;
  5. Создать и заполнить свойства необходимых параметров. Тобишь имена, типы, значения;
  6. Добавить параметры в коллекцию параметров команды;
  7. Открыть соединение (именно это я забыл сделать на собеседовании);
  8. Выполнить команду и получить объект DbDataReader;
  9. Вчитать данные из ридера;
  10. Закрыть и уничтожить ридер (можно просто уничтожить);
  11. [Вообще на предыдущем этапе многие и бросают и все работает, но я доведу до конца.] Уничтожить команду. Вопрос, конечно философский, но раз команда реализует IDisposable, то уничтожить ее дело чести для меня, не вдаваясь в подробности реализации. А подробности бывают разные. Конечно, если мы хотим сделать reuse этой команды, то уничтожать ее не надо пока;
  12. Закрыть соединение (процедура крайне желательная, если не последует другая команда сразу за выполнением очередной);
  13. Уничтожить соединение.
Использование DbDataAdapter-а лишь расширит этот перечень. Ничего не забыл? :) Сосредотачиваясь на таком объеме инструкций легко забыть, для чего идешь в БД... Шутка! Но не без доли правды. Так вот, есть трюки, позволяющие сделать это все в рамках одного вызова большого метода. И этот вызов будет сосредоточен в одном месте, охвачен одним взглядом, а не размазан по коду дизайнера подальше от глаз программиста.

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

1 комментарий:

  1. Да, ADO.NET я пользуюсь нечасто, и каждый раз как с чистого листа - что за чем идёт? Кому на кого надо ссылку давать? Посмотрим, что предлагает автор, очень интересно.. :)

    ОтветитьУдалить