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

В четырнадцатом выпуске рассылки '.Net Собеседник' вы можете познакомиться с


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

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

Содержание
  1. От автора
  2. Обзор новостей
  3. Управляем вложенными транзакциями  
  4. Время кода - Помещаем данные в ComboBox
  5. Форумы .Net на www.sql.ru

От автора

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

Сегодня опишу, пожалуй, самый быстрый способ наполнения DataGrid’a с помощью DataReader’a, а кроме того, использование строки подсоединения к БД, которая хранится в файле web.config.

Итак, в файле Web.Config можно хранить некоторые общие для всего приложения данные, например – строку подключения к БД.


</system.web>
<appSettings>
<addkey="con4all"value="datasource=myserver1;initialcatalog=mydatabase1;persistsecurityinfo=false;uid=myuid;pwd=mypwd;packet size=4096"/>
</appSettings>
</configuration>

Взять эту строчку подключения можно, подключив пространство имён System.Configuration к приложению и написав следующее –

SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationSettings.AppSettings["con4all"];

А заполнить DataGrid (здесь - DataGridForFill) можно таким образом –

SqlCommand scom = new SqlCommand();
scom.Connection = con;
scom.CommandType = CommandType.StoredProcedure;
scom.CommandText = "[SELECT_STORED_PROCEDURE]";
scom.Parameters.Add(new System.Data.SqlClient.SqlParameter("@name", System.Data.SqlDbType.VarChar, 50, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "", System.Data.DataRowVersion.Current, null));

scom.Parameters["@name"].Value = name;
DataGridForFill.DataSource = scom.ExecuteReader();
DataGridForFill.DataBind();

Заодно показано, как использовать хранимые процедуры с параметрами – в данном случае здесь используется параметр @name.

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

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

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

  1. Вышел OraDirect .NET Data Provider 2.30 от Core Lab
    Core Lab объявила о выходе версии 2.30 OraDirect .NET, 100% .NET провайдера данных для Oracle на платформе MS .NET Framework. Новая версия имеет поддержку Oracle 10g, типов XMLType, BINARY_FLOAT и BINARY_DOUBLE, а также Oracle 10g Instant Client. Доступен новый класс OraclePermission.
  2. dtSearch выпустила dtSearch Network с Spider V6.33
    dtSearch Network позволяет осуществлять поиск текста в корпоративной сети. Предлагает больше двух дюжин индексированных и неиндексированных настроек для поиска текста для всех популярных типов файлов.
  3. Вышел Shell MegaPack.Net 5.2
    Sky Software объявила о выходе Shell MegaPack.Net 5.2. Содержит элемент управления подобный TreeView, элемент управления список файлов/папок, ниспадающий список доступных дисков, имитируя функциональность Windows Explorer. Поддерживает множество разных визуальных стилей, технологию перетащи-и-брось, иконки, контекстные меню и т.д.
  4. Набор только чисел в строках ввода приложений ASP.NET
    Каким образом разрешить набор только чисел в приложениях ASP.NET с помощью компонента CustomValidator и рассказано в этой статье.
  5. Вышел Gnostice PDFtoolkit ActiveX/.NET 1.0
    Gnostice выпустила PDFtoolkit ActiveX/.NET, мощный компонент для управления PDF документами для Microsoft Visual Studio/ .NET. PDFtoolkit поддерживает заполнение и чтение PDF-форм, сжатие, безопасность, добавление и слияние нескольких документов PDF; установку закладок и много других функций.
  6. Вышел Aspose.Word 1.4
    Aspose.Word - компонент .NET создания отчётов в формате Word без использования Microsoft Word.
  7. Microsoft приобрела Aspose.Excel
    Прекрасный день для Aspose - Microsoft Corporation купила Aspose.Excel.
  8. Вышел Aspose.Excel 1.9
    Aspose.Excel - компонент .NET, позволяющий читать и писать документы Excel без использования Microsoft Excel.
  9. Вышел Gnostice eDocEngine ActiveX/.NET 1.0
    Gnostice объявляет о выходе Gnostice eDocEngine ActiveX/.NET – набор компонент для создания документов в среде Microsoft Visual Studio/ .NET. eDocEngine позволяет вам создавать электронные документы в 18 популярных форматах, включая PDF, RTF, HTML, Excel, TIFF, SVG, PNG, JPEG, Metafile и т.п.
BUGs, FIXes and HOW TO's -
  1. FIX: Your computer stops responding when you use Microsoft OLE DB provider for Oracle
  2. How to poll for changes to the Active Directory by using Visual C# .NET
  3. The .NET client application cannot catch the events that are raised by an Office Spreadsheet 11.0 ActiveX control
  4. You experience poor performance when you host ASP.NET applications in multiple application pools on a multiprocessor server
  5. An unhandled exception of the 'System.ArgumentException' type occurs after you rename the columns of a DataSet object
  6. Changes to datagrid text are lost in Visual C# .NET 2003 project

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

Управляем вложенными транзакциями

Управляем вложенными транзакциями

ЯЗЫК: C#.Net
Автор статьи: Brian Noyes, http://www.aspnetpro.com/

ПЕРЕВОД: Чужа В.Ф. ака hDrummer


ADO.NET позволяет вам легко оформить несколько обращений к БД в виде одной транзакции. Однако программисты часто неохотно используют такой подход, поскольку они полностью не понимают взаимодействие между транзакциями, объявленными в коде ADO.NET и транзакциями, использующимися в хранимых процедурах (ХП). Ситуация часто усугубляется исключениями, вызванными SQL Server’ом при использовании вложенных транзакций с ХП, которые сами используют транзакции. В этой статье мы проясним указанные моменты, и я покажу вам, как использовать вложенные транзакции и правильно обрабатывать ошибки.

Транзакции на стороне SQL Server

Первым делом необходимо уяснить, каким образом транзакции работают внутри БД. Транзакции позволяют вам быть уверенным, что изменения, сделанные в БД в рамках транзакции, будут или все приняты или все отвергнуты. Есть несколько уровней изоляции, которые определяют, могут ли данные, считанные во время работы транзакции, быть изменены в то время, пока не закончила работу эта транзакция. По умолчанию уровень установлен в Read Committed, что говорит о том, что данные могут быть изменены в контексте незавершенной транзакции, но вы не получите данных, которые только частично изменены из другой транзакции. Если же вы хотите убедиться в том, что данные запроса не меняются другой транзакцией до тех пор, пока не завершена ваша транзакция, вам необходимо установить уровень изоляции в Repeatable Read или Serializable. Более подробно об этих уровнях можно прочитать в SQL Books online, также известном как BOL. Каждый индивидуальный запрос, исполняемый SQL Server’ом, автоматически оформляется как транзакция. Допустим, у вас есть команда update, модифицирующая 100 записей в таблице. Если что-то пошло не так на записи номер 99, то все изменения откатываются и, после возникновения ошибки, никаких в таблице модификаций вы не увидите. Если же вы используете ХП для доступа к вашей БД, эти ХП также должны оформлять SQL-команды в транзакции уровня этой ХП. Например, рассмотрим простую ХП:

CREATE PROCEDURE AddOrder
@CustomerName nvarchar(50),
@StatusID int
AS
 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
 BEGIN TRANSACTION
 IF NOT EXISTS
  (SELECT StatusID FROM OrderStatus
  WHERE StatusID = @StatusID)
 BEGIN
  ROLLBACK TRANSACTION
  RAISERROR('Вы должны передать существующий Status ID',11,1)
 RETURN
 END

INSERT INTO Orders (CustomerName, StatusID)
 VALUES (@CustomerName, @StatusID)
 COMMIT TRANSACTION
RETURN

Эта ХП использует свою собственную транзакцию для команд SELECT и INSERT. SELECT убеждается в том, что передан существующий StatusID (например для того, чтобы убедиться, что не нарушена ссылочная целостность), а INSERT добавляет запись к таблице Orders. Если у вас несколько запросов в ХП выполнены виде транзакции, возможно, вы захотите управлять транзакциями на этом уровне. Откат транзакции в любом месте перед командой COMMIT TRANSACTION предупредит запись изменений в БД.
Вы можете подумать, что необязательно включать оператор SELECT в транзакцию, поскольку он не меняет БД. Во многих ситуациях вы будете не правы. Выполнение подобных запросов похоже на программирование многопоточных приложений. Вы должны предполагать, что между выполнением команд SELECT и INSERT кто-то может модифицировать таблицу OrderStatus и удалить значение, которое вы только что проверяли на существование, в результате команда INSERT не выполнится. Вам часто придётся убеждаться в том, что все запросы, которые вы выполняете, выполняются с одним и тем же состоянием БД и лучший метод убедиться в этом – оформить такие запросы в виде транзакции и при необходимости установить уровень транзакции в Repeatable Read или Serializable.
Если оператор INSERT приводит к ошибке, то транзакция автоматически откатывается. Поэтому нет необходимости явно отслеживать такие ошибки и откатывать такие транзакции после каждой команды. Однако могут быть ситуации, когда вы ожидаете результат исполнения такой процедуры для дальнейших действий и, если они отсутствуют, вам необходимо явно откатывать транзакцию.

Транзакции в ADO.NET

А что если вам надо выполнить несколько ХП из кода на C# согласно тому же принципу ‘всё или ничего’? Как раз для этих целей ADO.NET содержит класс SqlTransaction. Технология достаточно проста - вызываете BeginTransaction для объекта SqlConnection, чтобы получить новый объект транзакции, если всё Ок - вызываем SqlTransaction.Commit, если не всё так хорошо, как хотелось - SqlTransaction.Rollback.

// создаём соединение (conn)
// объявляем транзакцию
SqlTransaction trans;
// создаём команды
try{
conn.Open(); // открываем соединение
trans = conn.BeginTransaction();
// ассоциируем транзакции с командами
// исполняем запросы
// если всё ОК - подтверждаем
trans.Commit();
}
catch (Exception ex)
{
// если нет - откатываем
if (trans != null) trans.Rollback();
}
finally
{
conn.Close();
}

В общем, это просто, не так ли? Хитрость заключается в том, чтобы правильно обрабатывать исключения в блоке catch и понимать те исключения, которые вызываются. Если вы вызываете ХП, которые не управляют своими транзакциями, не должно быть никаких проблем. Если ошибка возникает где-то во время выполнения вашего кода, то будет вызвано исключение SqlException, которое попадёт в блок catch. Код в этом блоке вызовет Rollback и никакие обновления с начала транзакции не попадут в вашу БД.

Не пугайтесь своих вложенных инстинктов

А что же происходит, если ХП, которые вы вызываете, сами управляют своими транзакциями? Не означают ли эти вызовы COMMIT TRANSACTION внутри ХП того, что изменения будут внесены в БД не смотря на откат в коде на C#? Ответ – нет, и причина такого ответа в том, как выполняются вложенные транзакции на SQL Server’e. Когда вы стартуете транзакцию в своём коде, на самом деле вы стартуете её на сервере, все последующие транзакции являются для неё вложенными, до тех пор, пока кем-то не будет дана команда Commit или Rollback. Этим кем-то может быть ваш код на C#, код в ХП или сам SQL Server, если на нём произойдёт ошибка.
Если ХП сама пытается стартовать транзакцию с помощью BEGIN TRANSACTION, то она просто попадает в область видимости существующей транзакции. Поэтому любой откат, произошедший внутри ХП, откатит и внешнюю транзакцию, стартовавшую в вашем коде, чего на самом деле нам и хотелось.
Единственно, о чём надо упомянуть, так это о том, что в случае отката транзакции вызывается SqlException с таким описанием:

"Transaction count after EXECUTE indicates that a COMMIT or
ROLLBACK TRANSACTION statement is missing. Previous
count = 1, current count = 0."

Это исключение вызывается SQL Server’ом, который видит, что при входе в ХП была транзакция, однако при выходе из ХП её не осталось, поскольку был откат. Поскольку такая ситуация обрабатывается как исключительная, то вы её отловите. Никакого вреда повторный Rollback не нанесёт, поэтому просто вызывайте Rollback в обработчике исключений; и не надо его отлавливать по какому-то условию, основывающемуся на информации об исключении.

Что ещё можно сделать, так это убрать информацию ошибки, содержащую количество транзакций, особенно если вы собираетесь где-нибудь вести лог ошибок. По всей вероятности такая информация вызовет у просматривающего недоумение, особенно если он не понимает механизм действия вложенных транзакций. Путём итерации через коллекцию Errors можно получить все ошибки, номер ошибки SQL для счетчика транзакций равен 266, поэтому такую ошибку можно выделить и обработать отдельно – например, просто ни в какой лог её не писать.
В коде для скачивания находится небольшой проект, с которым можно поиграться и в котором продемонстрированы основные моменты работы с БД, вышеизложенные в данной статье.
Код к этой статье можно скачать здесь - скачать.

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

Время кода

Помещаем данные в ComboBox

ЯЗЫК: C#
АВТОР: Huseyin Altindag,
http://www.csharphelp.com/
ПЕРЕВОД: Чужа В.Ф ака hDrummer


В этой статье описан мой собственный подход, как получить данные из ComboBox. Также показано, как подсоединиться к БД MS-Access, которая включена в проект (sudentDB.mdb).

После того как на нескольких форумах я видел вопросы по заполнению ComboBox'a и получению данных из него, я решил написать вот такую программу.
Приложение позволяет вам выбрать StudentID и отображать данные полей StudentID, Student Subjet и Student Name из таблицы в строках ввода.

Описание кода

После подсоединения к БД 'student' в методе 'fnGetConnectedToDatabase' (в комментариях есть небольшая помощь по соединению с БД) я присваиваю в цикле foreach к трём переменным (strStudentID,strStudentSubject,strStudentName) значения трёх полей. Не забудьте создать новую папку DATA на вашем дискке (здесь - на D:) и скопировать туда файл 'studentDB' и файл 'imgCombobox.jpg'. Переменная 'strTemp' содержит все три значения переменных с тремя звёздочками, как здесь - 'strTemp=WS-P1998*Philosophy*Jo Marks', поскольку я хочу разбить 'strTemp' на три части, используя разделитель *. Позже я отображу эти три части в строках ввода. А потом я помещу значнение переменной 'strTemp' в ArrayList с индексом 'i'. А потом запишем каждое значение strStudentID в ComboBox 'this.comboBox1.Items.Add(strStudentID);' .

private void fnGetConnectedToDatabase()
{
...
...
foreach (DataRow myRow in myDataset.Tables["student"].Rows)
{
strStudentID =(string) myRow["studentID"];
strStudentSubject=(string) myRow["StudentSubject"];
strStudentName=(string) myRow["StudentName"];
strTemp=strStudentID+"*"+strStudentSubject+"*"+strStudentName;
//поместим strTemp в строковый массив strArraylist с индексом int i(index for strArraylist)
this.strArraylist[i++]=strTemp;
//отображаем в ComboBox только strStudentID
this.comboBox1.Items.Add(strStudentID);
} }

Как только происходит выбор StudentID из ComboBox исполняется метод comboBox1_SelectedIndexChanged -

private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
string delimstr="*";
char[] delimeter=delimstr.ToCharArray();
string[] splitstr=null;
splitstr=this.strArraylist[this.comboBox1.SelectedIndex].Split(delimeter,3);
//теперь выполним присваивание
this.textBox1.Text=splitstr[0];
this.textBox2.Text=splitstr[1];
this.textBox3.Text=splitstr[2]; }

С помощью строки 'this.strArraylist[this.comboBox1.SelectedIndex]' я получаю из ArrayList строку в виде 'WS-P1998*Philosophy*Jo Marks' по индексу 'this.comboBox1.SelectedIndex', а спомощью Split(delimeter,3) я разбиваю её на три слова
'WS-P1998' в splitstr[0]
'Philosophy' в splitstr[1]
'Jo Marks' в splitstr[2]
Теперь можно присвоить содержимое 'splitstr' с индексами 0,1,2 для комопнент TextBox textBox1, textBox2 и textBox3. И всё. Здесь можно скачнуть проект - исходный код проекта..

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


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

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

SqlCommand.CommandTimeot = 0 -> General Network Error
А кто то пользовался уже AtomsFramework?
DataSet визуально
Схема отладки веб-сервиса, запись в файл и системный дебаггер
Преобразование типов данных при формировании запроса
Проблема с печатью рамок в полях ввода
вместо Edit картинка
Visual Studio .NET + Framework 1.1
Пример GLOBAL.ASA
Devexpress Combo Filter
Архивация и DataGrid?
Редактор форм
Могут ли визуально отображаться UserControl?
Объектная модель Chart в Crystal report
Infragistics Web Calendar



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



Чужа Виталий Ф. aka hDrummer,
hdrummer@sql.ru - жду ваши предложения, вопросы и замечания.


Рассылки Subscribe.Ru
.Net Собеседник - Новости мира Net, C#, ASP.Net


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу


В избранное