Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

В этом номере:


Информационный Канал Subscribe.Ru

.Net Собеседник #45

Содержание
  1. От автора
  2. Обзор новостей
  3. Обработка транзакций в ADO.NET 2.0
  4. Время кода - Ключевые слова на C# : B
  5. Форумы .Net на www.sql.ru

От автора

Здравствуйте, коллеги!

После долгих раздумий и сомнений, а также полугодовой одновременной работы и над рассылкой и над журналом, я понял, что два таких крупных проекта одновременно мне не потянуть.  В результате, я решил объединить эти два проекта. Как это будет выглядеть? Рассылка станет, в какой-то степени, дайджестом журнала. Все рубрики, которые в ней были, останутся в неизменном виде. Что же такое будет в журнале, чего не будет в рассылке?

1. Обзор новостей. В рассылке новости будут идти "одной" строкой. В журнале же будут полноценные обзоры возможностей продукта.
2. Статьи. В журнале будут полные версии статей, со схемами и диаграммами. В рассылке - сокращенные.
3. Чего в журнале не будет - так это неотвеченных вопросов на форумах .Net на сайте sql.ru.
4. Также в рассылке не будут публиковаться интервью с интересными людьми компьютерной индустрии.

И ещё. Четвёртый номер журнала будет выложен в полном виде, таким, каким его получат подписчики. Однако, в дальнейшем, в журнале будут материалы, доступные только подписчикам, что вполне естественно и понятно. Напомню, что подписаться в Украине можно через каталог Укрпочты, индекс журнала 91132. Россияне пока могут подписаться только через редакцию (что, впрочем, могут сделать и жители Украины), страница с документами для подписки находится здесь - http://dotnetgrains.sql.ru/alg/algsubscribe.htm.

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

На этом всё- желаю интересного чтения.

{К содержанию}

Обзор новостей

  1. Microsoft не станет поставлять Monad с Windows Vista
    Появились сообщения о том, что Microsoft убрала оболочку скриптов Monad из Windows Vista, после появления первых сообщений о том, что под это оболочку уже написано несколько вирусов.
  2. Тестирование мастера миграции приложений ASP.NET
    Команда ASP.NET ищет разработчиков, желающих принять участие в тестировании мастера миграции приложений ASP.NET 1.x на версию 2.0. Мастер миграции автоматически конвертирует ваше приложение в версию 2.0, включая ссылки на сборки, позволит отдельным классам иметь доступ к веб-формам и пользовательским элементам управления, обработает классы и структуры в вашем проекте.
  3. Вышел Shell MegaPack.Net 7.0
    Shell MegaPack является набором элементов управления графического интерфейса пользователя, полностью повторяющий пользовательский интерфейс проводника Windows. Этот набор содержит элемент управления иерархическое дерево, элемент управления просмотра папок и файлов, а также элемент управления, с помощью которого можно выбрать диски, доступные системе. Каждый элемент полностью поддерживает все особенности соответствующих элементов проводника Windows – пиктограммы, детализированный и групповой просмотр, технологию перетащи-и-брось, иконки, контекстные меню, подсказки, переименование и т.д.
  4. Разработчики хотят Visual Studio/VSTS Beta 3
    Поскольку версии Visual Studio 2005 и Visual Studio Team System Бета 2 нестабильны, разработчики призывают к задержке выпуска окончательной версии продукта. Вместо этого они предлагают выпустить Бету 3, а окончательный выпуск перенести на несколько месяцев.
  5. 101 пример для Visual Studio 2005
    Microsoft выпустила сборник, содержащий 101 пример использования платформы .NET Framework 2.0 на языках Visual Basic и C# для Visual Studio 2005. Сборник содержит примеры решения типовых задач с использованием базовой библиотеки классов, доступа к данным, веб-разработки и разработки под WinForms.
  6. Вышел .netCHARTING 3.3
    .netCHARTING – набор компонент для создания различных диаграмм и графиков в приложениях .NET. В число новых видов графиков входят 3D сплайновые диаграммы, поддержка технлогией SmartPalette синхронизации цветов среди графиков и областей графиков, новые статистические, финансовые системы и системы прогнозирования, возможность сохранять и восстанавливать состояние в XML, новые настройки меток.
  7. SecureString в .NET 2.0
    Пол Главич в своём блоге описал новый класс в .NET 2.0, который называется SecureString.
  8. Локализация в ASP.NET 2.0
    Ви Минг Ли опубликовал статью на сайте ONDotnet.com, в которой рассказывает о том, каким образом можно осуществить явную и неявную локализацию приложения, написанного на ASP.NET 2.0
  9. 9Rays.Net выпустила новый продукт для .NET – OLAP ModelKit
    9Rays.Net объявила о выходе OLAP-компонента для .NET – OLAP ModelKit.

{К содержанию}

Статья номера

Обработка транзакций в ADO.NET 2.0

ЯЗЫК: C#
Автор статьи: В.Райан, полную версию статьи читайте в №4 журнала "Алгоритм"
 
ПЕРЕВОД: Чужа В.Ф. ака hDrummer

Транзакции

Одной из существенно улучшенных технологий в ADO.NET 2.0 стала обработка транзакций. Поскольку окончательный продукт ещё не выпущен, то всё может измениться, но уже на данный момент работать с ними стало гораздо легче. В первых версиях ADO.NET вы могли работать с транзакциями несколькими способами. Если вы работали с одной БД, то могли создать экземпляр объекта IDBTransaction (http://msdn.microsoft.com/library/default.asp?url= /library/en-us/cpref/html/frlrfsystemdataidbtransactionclasstopic.asp), прицепить его к своему соединению, выполнить необходимые действия и записать или откатить их в зависимости от результата. К достоинствам такого подхода можно отнести тот факт, что всё это делалось на стороне клиента, однако не все были этим довольны. Похожий подход просто заключал вашу транзакцию в хранимую процедуру, а затем следовало её исполнение. В целом, я думаю, такой подход более оправдан, но и в этом случае были проблемы – например, такая реализация была тесно связана с используемой базой данных. Таким образом, если вы хотели переместить файл, отослать сообщение в очередь сообщений MSMQ, а затем обновить БД на Microsoft SQL Server, то вам бы пришлось сделать достаточно много работы. Этот процесс сильно упростили, и, во что трудно поверить, он действительно работает. Буквально через секунду мы погрузимся в недра кода примера, но дайте мне ещё раз убедиться в том, что вы поняли различие к которому я вас подвожу: теперь, как и ранее, есть два вида транзакций – локальные и распределённые. Распределённые транзакции охватывают несколько объектов сети, в то время как локальные – только один. Так или иначе, можно воспользоваться преимуществами использования объекта TransactionScope – просто для того, чтобы облегчить себе жизнь.

Простая транзакция в ADO.NET 2.0:

bool IsConsistent = false;
using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope())
{
      SqlConnection cn = newSqlConnection(CONNECTION_STRING);
      string sql = "DELETE Categories";
      SqlCommand cmd = newSqlCommand(sql, cn);
      cn.Open();
      cmd.ExecuteNonQuery();
      cn.Close();
//Согласно значению этого свойства, транзакция запишется в БД, если
//является успешной. Если она не будет успешной, то свойство не
//установится и транзакция не запишется

      ts.Consistent = IsConsistent;
}

Итак, я создал запрос, очищающий таблицу, обернул его в транзакцию и убедился в том, что она не выполнится. Поступив таким образом, я добился того, что таблица останется такой же, какой была перед вызовом ExcecutNonQuery. Так что же здесь нового? Отметьте, что собственно сам объект соединения находится внутри транзакции, так что он автоматически принимает в ней участие. Всё, что нужно для записи или отката транзакции – установить свойство Consistent в True или False. Более реалистичный пример приведен ниже, в нем сделано несколько небольших изменений:

Слегка улучшенная реализация:

bool IsConsistent = false;
using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope())
{
     SqlConnection cn = newSqlConnection(CONNECTION_STRING );
     string sql = "DELETE Categories";
     SqlCommand cmd = newSqlCommand(sql, cn);
     cn.Open();
     try
     {
          cmd.ExecuteNonQuery();
          IsConsistent = true;
     }
     catch (SqlException ex)
     {
//Здесь можно добавить дополнительную обработку ошибок
     }
     cn.Close();
//Поскольку изначально переменная установлена в false, то транзакция
//запишется, если всё отработает нормально
     ts.Consistent = IsConsitent;
}

Этот пример больше напоминает примеры работы с транзакциями в ранних версиях ADO.NET, проще говоря, если всё отрабатывает, то происходит фиксация изменений, если же нет – откат. Вряд ли имеет смысл использовать такой вариант, поскольку здесь нет никакого уменьшения сложности кода. Для того чтобы увидеть действительную элегантность и мощь этого объекта, необходимо обратиться к распределённому сценарию. Представим себе в действительности сложную ситуацию. Допустим, вам нужно очистить таблицу в БД Yukon, а затем вам нужно очистить связанную с ней таблицу из другой БД. И всё это либо должно произойти вместе, либо обе таблицы должны остаться нетронутыми.

bool IsConsistent = false;
using (TransactionScope ts = new TransactionScope())
{
  using (SqlConnection cn = new SqlConnection(YUKON_CONNECTION_STRING))
  {
    string sql = "DELETE Products";
    SqlCommand cmd = new SqlCommand(sql, cn);
    cn.Open();
    try
    {
       cmd.ExecuteNonQuery();
       using(SqlConnection cnn = new SqlConnection(CONNECTION_STRING))
       {
            string sql_2 = "DELETE Categories";
            SqlCommand cmd2 = new SqlCommand(sql_2, cnn);
            cnn.Open();
            cmd.ExecuteNonQuery();
            cnn.Close();
       }
           IsConsistent = true;
     }
     catch (SqlException ex)
     {
// Здесь можно добавить дополнительную обработку ошибок
     }
     cn.Close();
  }
  ts.Consistent = IsConsistent;
}

Короче говоря, всё выглядит достаточно просто. Оберните всё объектом TransactionScope, и он позаботится обо всём остальном за вас. Что это значит? Это значит, что он определит, какая транзакция вам нужна – локальная или распределённая и поведёт себя соответственно. То есть поучаствует там, где необходимо, в распределённой транзакции или отработает её локально. Заметьте, что первая строка соединения указывает на БД Yukon (SQL Server 2005). Таким образом, мы можем воспользоваться преимуществами «делегирования». Это прикольный способ сказать: «Нам не нужна эта ужасная распределённая транзакция, мы используем Yukon", после чего не использовать её до тех пор, пока это не станет необходимо. А теперь, если вы вырежете внутренние строчки, которые обращаются к ДРУГОЙ базе данных, то всё останется в рамках локальной транзакции. Однако, как только мы вновь вставим обращение к другой базе данных, сразу автоматически вернёмся к распределённой транзакции. Всё это наводит на мысль о том, что они работают в двух разных контекстах, не так ли? В конце концов, вам необходимо перейти в режим DT (распределённой транзакции), как только дело доходит до обращения ко второй базе, а ведь до того транзакцию можно было считать локальной! Вообще-то, правильный ответ НЕТ, и не падайте на пол! Хотя это и действительно удивляет. Как только код доходит до точки, после которой не возможно работать локально, всё приводится в соответствие для работы с распределённой транзакцией. И здесь реализована поддержка не только Microsoft SQL Server - Oracle b MSMQ также поддерживаются. Также высока вероятность того, что и поддержка файловой систtvs будет включена в финальную версию.
Так что же, работают ли те же самые правила, если мы соединяемся с Oracle или MSMQ, а не с SQL Server 2000? Во всех смыслах этот транзакционный компонент будет работать одинаково. Если вы ранее использовали COM+, то, вне всяких сомнений, вы понимаете насколько такая реализация проще. Если же нет, то просто наберите строчку «Distributed Transaction COM+» в Google и почитайте, что там об этом пишут. Вот тогда вы поймете, насколько всё стало проще. Даже если вы не встречались ни с одним из перечисленных сценариев, просто взгляните на нестабильную по своей природе работу транзакций на стороне клиента в ADO.NET и вы сразу поймёте, насколько всё теперь здорово.
Однако, не смотря на такие глобальные перемены, наверняка найдутся люди, которым это всё придётся не по душе. Что ж, отлично. Вы не обязаны использовать объект TransactionScope; можете просто не обращать на него внимания. Если вам нравится писать сотни строк кода, а также вы считаете, что с точки зрения безопасности полезно заниматься бессмысленными вещами, делайте так, как вам нравится.

{К содержанию}

Время кода

Ключевые слова на C# : B

ЯЗЫК: C#
Автор статьи: Чужа В.Ф.
, полную версию статьи читайте в №4 журнала "Алгоритм"

Вступление

Ключевое слово base используется для доступа к членам базового класса из производного класса. Доступ к членам производного класса возможен в конструкторе, методе объекта или его свойстве.
1. Ключевое слово base можно использовать для вызова метода базового класса, если этот метод был перекрыт (или перегружен) другим методом производного класса. Причём перекрытый(перегруженный) метод можно вызывать из любого другого метода производного класса, не обязательно из перекрывающего. В Листинге 1 мы создаём базовый класс BasicHero, который имеет конструктор, инициализирующий член класса message типа string, а также метод SayMessage, который выводит на экран значение члена класса message. Затем создаём наследник этого класса – класс HeroWithoutRapier, в котором перегружаем метод SayMessage. Однако мы делаем допущение, что нам требуется сделать вызов перегруженного метода базового класса. В этом случае нам приходит на выручку ключевое слово base. Обратите внимание также на два момента. Первый – при перегрузке метода рекомендуется явно использовать ключевое слово new, указывающее, что метод был перегружен сознательно, а не в результате недосмотра. Второй – при перегрузке метода мы беспрепятственно изменили область его видимости на public. Подобным же образом можно использовать доступ к членам базового класса и в свойствах класса-наследника.

using System;

namespace Keyword.Base
{
class TestKeywordBase
{
[STAThread]
static void Main()
{
HeroWithoutRapier Roland = new HeroWithoutRapier();
Roland.SayMessage();
}
}

class BasicHero
{
string message;
public BasicHero()
{
message = "Я герой!";
}
protected void SayMessage()
{
Console.WriteLine(message);
}

}

class HeroWithoutRapier : BasicHero
{
public void SayMessage()
//здесь рекомендуется использовать ключевое слово new, для того, чтобы
//было видно, что данный метод перекрывает родительский метод с тем же именем
//не случайно.
{
//Можем вызвать метод базового класса из производного класса,
//использовав ключевое слово base
base.SayMessage();
//а затем расширить функциональность метода производного класса
Console.WriteLine("Но где же моя шпага?");
}
}
}
Листинг 1. Использование ключевого слова base в методе производного класса

2. Также это ключевое слово можно использовать при создании объекта класса, указав его в конструкторе класса. Так мы сообщаем о своём намерении воспользоваться конструктором базового класса. В Листинге 2 мы также имеем базовый класс BasicHero, а также два конструктора – один по умолчанию, а второй параметризованный. Метод SayMessage по-прежнему выводит на консоль член класса message. Затем мы создаём класс-наследник HeroWithOwnMessage, который имеет конструктор по умолчанию, вызывающий конструктор по умолчанию базового класса, а также параметризованный конструктор, вызывающий параметризованный конструктор всё того же базового класса. В обоих случаях такая функциональность становится доступной с помощью ключевого слова base.

using System;

namespace Keyword.Base
{
class TestKeywordBase
{
[STAThread]
static void Main()
{
HeroWithOwnMessage Harold = new HeroWithOwnMessage("Я Гарольд!");
Harold.SayOwnMessage();
}
}

class BasicHero
{
//изменяем модификатор доступа к члену класса так,
//чтобы член класса был виден потомку
protected string message;
public BasicHero()
{
message = "Я герой!";
}
public BasicHero(string msg)
{
message = msg;
}
protected void SayMessage()
{
Console.WriteLine(message);
}

}

class HeroWithOwnMessage :BasicHero
{
//вызываем конструктор базового класса без параметра
public HeroWithOwnMessage(): base()
{

}
//вызываем конструктор базового класса с параметром
public HeroWithOwnMessage(string msg): base(msg)
{

}
//а теперь можно вот таким образом вывести сообщение - с помощью обращения к
//члену базового класса
public void SayOwnMessage()
{
Console.WriteLine(base.message);
}

}
}

Листинг 2. Использование ключевого слова base для обращения к конструктору базового класса.

Хотя нужно заметить, что во втором случае – случае с параметризованным конструктором, мы могли поступить интереснее, так, как показано в Листинге 3. В этом случае для Варианта 1 сначала вызовется конструктор базового класса, а затем – наш конструктор, который, фактически, сведёт на нет присвоение, выполненное в конструкторе базового класса. В случае Варианта 2 один из параметров используется в конструкторе базового класса, а второй – в конструкторе класса-наследника. Такой подход позволяет более гибко подходить к использованию как конструкторов класса-наследника, так и конструкторов базового класса.

Вариант 1. 
public HeroWithOwnMessage(string msg): base()
{
base.message = msg;
}
Вариант 2.
public HeroWithOwnMessage(string msg, int i): base(msg)
{
int j = i;
}
Листинг 3. Варианты вызова конструктора базового класса.

Напомню, что термины «перекрытие» и «перегрузка» отличаются тем, что при перекрывании метода (свойства) мы изменяем его поведение в классе наследнике, а перегрузка метода (свойства) просто приводит к использованию другого метода (свойства) с тем же именем внутри класса.


{К содержанию}

Форумы .Net - вопросы оставшиеся без ответа

BdpException: Заданное приведение является недопустимым. DataGrid и Request.Form
[Off] XML-XSLT
Ошибка при открытии проекта в Студии при помощи SourceSafe
Форматы справок
объединение в транзакцию серии обновлений связанных таблиц в DataSet
MS Word и web приложение
Вопрос про кодировку
Удаленный запуск dll
Помогите ламеру с С#
Ora direct .Net Data Provider

На этом сорок пятый выпуск .Net Собеседника закончен.
До следующего номера.


Чужа Виталий Ф. aka hDrummer, MCAD, MCDBA, MCP
hdrummer ухо gmail точка ru - жду ваши предложения и замечания.



Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.dotnetgrains
Отписаться
Вспомнить пароль

В избранное