Глава 4 Взаимодействие с базами данных

Постановка задачи
Создание базы данных
Ввод данных с Web-страницы
Объект SqlConnection
Объект SqlCommand
Поиск и отображение информации
Объект SqlDataAdapter

ADO.NET
Извлечение данных из XML-файлов

Постановка задачи

Естественно, при разработке сколько-нибудь серьезного сайта нельзя обойтись без системы управления базами данных. Для сайтов, созданных с помощью технологии ASP.NET, самым естественным выбором, пожалуй, будет сервер MS SQL Server 2000. На самом деле можно использовать практически любую СУБД, для которой в системе установлен ODBC-драйвер, но необходимо осознавать, что сервер MS SQL Server 2000 создан Microsoft, как и технология Microsoft .NET, поэтому связь между Web-приложениями и базами данных, функционирующими под управлением MS SQL Server 2000, будет практически прозрачна.

Установка SQL Server 2000 в конфигурации Enterprise на платформы Windows 2000 или Windows XP достаточно тривиальна и не вызывает никаких проблем. После завершения программы инсталляции в вашем меню Programs появится одна или несколько (в зависимости от выбранного комплекта утилит) новых групп программ, а сам SQL Server 2000 успешно стартует, о чем будет сигнализировать соответствующий значок.

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

Естественно, рассмотрение вопросов взаимодействия Web-приложений лучше всего проводить на примере. Чаще всего в литературе рассматривают примеры создания интернет-магазинов. Попробуем взять что-либо не столь распространенное. Например, сетевое агентство знакомств.

Потребуется создать сайт с возможностями поиска по базе данных, а также предусмотреть механизм ввода пользователями информации о себе. Естественно, это будет всего лишь учебный проект, поэтому будем использовать "облегченные" варианты баз данных. А теперь перейдем к непосредственной работе.

Создание базы данных

Прежде всего, необходимо создать саму базу данных, чтобы потом ее можно было подключить к создаваемому Web-приложению. Для этого следует запустить утилиту Enterprise Manager.

В левой части этой утилиты располагается дерево управления SQL-сервером. Необходимо раскрыть папку Databases. Для создания новой базы данных можно воспользоваться встроенным мастером SQL Server 2000, вызов списка встроенных мастеров производится либо нажатием кнопки Run a Wizard (Запустить мастер), располагающейся на основной инструментальной панели утилиты управления сервером, либо при помощи команды меню Tools | Wizards (Сервис | Мастера). При этом будет отображено диалоговое окно Select Wizard (Выбрать мастер),

В списке поставляемых мастеров нас будет интересовать мастер с наименованием Create Database Wizard (Мастер создания базы данных). Он позволяет создавать базы данных в визуальном режиме, без объявления их структуры при помощи SQL-выражения.

После запуска выбранного мастера, будет отображено диалоговое окно первого этапа его работы. Для начала необходимо будет ввести наименование создаваемой базы данных и расположение файлов самой базы данных и log-файла всех транзакций в файловой системе сервера. Внешний вид диалогового окна первого этапа работы мастера показан на рис. 4.3.

Для новой базы данных мы укажем наименование Dating, введя его в текстовое поле Database Name (Имя базы данных). Расположение файлов каждый может задать самостоятельно, это не должно вызывать затруднений. Стоит только заметить, что на используемом логическом диске должно быть достаточно места для наращивания объема данных.

После того, как указано наименование базы данных и расположение требуемых файлов, можно переходить к следующему этапу работы мастера, используя для того кнопку Next (Далее).

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

После указания размера файла, можно переходить к третьему этапу работы мастера.

Это диалоговое окно позволяет администратору указать порядок увеличения размера файла, содержащего базу данных в том случае, когда его размер все-таки превысит пределы, установленные администратором на предыдущем этапе работы мастера. Для автоматического увеличения размера файла (а это единственный разумный способ управления файлом, так как иначе он просто не будет увеличиваться, и ввод новых данных будет заблокирован) следует выбрать кнопку-переключатель Automatically grow the database files (Автоматическое увеличение размера файлов базы данных). После этого останется лишь указать, как именно будет рассчитываться дополнительный объем, выделяемый файлу. Если выбрать кнопку-переключатель Grow the files in megabytes (Увеличение размера файлов в мегабайтах), то каждый раз файл будет увеличиваться сразу на несколько мегабайт. Размер постоянного приращения можно задать в поле текстового ввода, связанного с данной кнопкой переключателем.

Также можно указать, что размер приращения будет исчисляться в процентах от размера основного файла. Для этого следует выбрать кнопку Grow the files by percent (Увеличение размера файлов в процентах). А в поле, связанном с этой кнопкой переключателем, необходимо задать размер приращения в процентах.

Группа органов управления Maximum file size (Максимальный размер файла) позволяет жестко задавать максимально возможный размер файла, содержащего данные. Как мы уже говорили ранее, неразумно задавать конкретный верхний предел размера файла. Поэтому рекомендуется выбирать кнопку Unrestricted file growth (Неограниченное возрастание размера файла), которая указывает серверу, что размеры файла можно увеличивать до заполнения всего свободного места на логическом диске.

После того, как указана политика увеличения размера файла, содержащего данные, можно переходить к следующему этапу работы мастера. Необходимо сказать, что последующие два этапа работы мастера практически идентичны второму и третьему этапу, когда устанавливались размеры и политика увеличения файла, содержащего данные. Но на четвертом и пятом этапах точно такие же операции будут производиться в отношении log-файла. Следует пояснить, что log-файл чаще всего занимает меньше места, чем файл с данными, однако все зависит от специфики базы данных. И после указания этих параметров мастер создания базы данных завершит свою работу.

Итак, база данных создана, но это еще далеко не все. Необходимо создать еще таблицы, входящие в состав этой базы данных. Для этого необходимо открыть базу данных и активировать группу Tables (Таблицы). В базе данных уже будет находиться несколько служебных таблиц, но нам необходимо сделать свою, в которой будут размещаться данные. Для этого следует выполнить команду меню Action | New Table (Действие Создать таблицу). При этом будет активировано диалоговое окно New Table in 'Dating' (Создать таблицу в 'Dating'),

Создание новой таблицы может проходить как в визуальном режиме, так и при помощи стандартного SQL-скрипта. Естественно, мы рассматриваем всего лишь тестовый пример, поэтому создадим облегченную версию таблицы, в которой будут храниться поля, содержащие имя посетителя (тип VarChar), пол (тип int), адрес электронной почты (тип char), поле, в котором будет храниться информация о пользователе (тип VarChar), поле, содержащее возраст пользователя (тип int). SQL-выражение, создающее подобную таблицу, выглядит следующим образом:

CREATE TABLE [dbo].[Dating] (

[USNAME] [varchar] (50) COLLATE Cyrillic_General_CS_AS NULL ,

[SEX] [int] NULL ,

[EMAIL] [char] (50) COLLATE Cyrillic_General_CS_AS NULL ,

[ABOUT] [varchar] (1000) COLLATE Cyrillic_General_CS_AS NULL ,

[AGE] [int] NULL , ) ON [PRIMARY]

Итак, база данных создана, и в ней объявлена таблица, в которой будут храниться основные данные. Так как пример будет упрощенным, то нам и не потребуется ничего, кроме этой таблицы.

Теперь рассмотрим структуру сайта, который будет взаимодействовать с созданной базой данных. Нам потребуется Web-страница для установки критерия поиска человека в общей базе данных, и, соответственно, Web-страница для вывода результатов поиска. Также потребуется и еще одна Web-страница, при помощи которой пользователи могли бы вводить данные о себе в базу данных. Вот с разработки этой Web-страницы мы и начнем.

Ввод данных с Web-страницы

Для начала нам придется разработать Web-страницу, при помощи которой пользователи смогут ввести информацию о себе в нашу базу данных. Этой Web-странице мы присвоим наименование "insert.aspx". На ней следует разместить поля текстового ввода и одну группу кнопок переключателей, при помощи которой пользователь будет указывать свой пол. Следовало бы также разместить на этой странице и механизм проверки достоверности, для контроля соответствия введенных данных установленным форматам. Иначе говоря, адрес электронной почты должен хотя бы соответствовать правилам написания этих адресов, а возраст должен быть целым положительным числом, находящимся в разумных рамках (допустим от 14 до 85), но не стоит в данном случае так сильно нагружать страницу органами управления. Как их использовать мы уже знаем, поэтому оставим маленький пример без них.

Итак, HTML-код Web-страницы в режиме разработки приведен в листинге 4.1.

Листинг 4.1 

<%@ Page Language="vb" AutoEventWireup="false"

Codebe-hind="insert.aspx.vb" Inherits="datingiWebForml"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD

HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<title>

</title>

<meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">

<meta name="CODE_LANGUAGE" content="Visual Basic 7.0">

<meta name="vs_defaultClientScript" content="JavaScript">

<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

</HEAD>

<body ms_positioning="GridLayout">

<form id="Forml" method="post" runat="server">

<asp:Label id="Labell" style="Z-INDEX: 101; LEFT: 49px;

POSITION: absolute; TOP: 20px" runat="server" Width="215px" Height="19px">BBeflMTe персональные данные</азр:Label>

<asp:Label id="Labe!2" style="Z-INDEX: 102; LEFT: 49px;

POSITION: absolute; TOP: 49px" runat="server">MMH</asp:Label>

<asp:TextBox id="TextBoxl" style="Z-INDEX: 103; LEFT: 49px;

POSITION: absolute;

TOP: 78px" runat="server" Width="221px" Height="24px"x/asp:TextBox>

<asp:Label id="Label3" style="Z-INDEX: 104; LEFT: 49px;

POSITION: absolute; TOP: 114px" runat="server">non</asp:Label>

<asp:RadioButtonList id="RadioButtonListl" style="Z-INDEX: 105; LEFT: 49px;

POSITION: absolute; TOP: 143px" runat="server">

<asp:List!tem Value="0" Selected="True">Жeнcкий</asp:ListItem> <asp:List!tem Value="l">Mya;cKoft</asp:ListItem> </asp:RadioButtonList>

<asp:Label id="Labe!4" style="Z-INDEX: 106; LEFT: 49px;

POSITION: absolute; TOP: 203px" runat="server">AЈpec электронной no4Tfci</asp:Label>

<asp:TextBox id="TextBox2" style="Z-INDEX: 107; LEFT: 49px;

POSITION: absolute;

TOP: 232px" runat="server"x/asp:TextBox>

<asp:Label id="Labe!5" style="Z-INDEX: 108; LEFT: 282px;

POSITION: absolute;

TOP: 46px" runat="server">Bo3pacT</asp:Label>

<asp:TextBox id="TextBox3" style="Z-INDEX: 109; LEFT: 284px;

POSITION: absolute; TOP: 79px" runat="server"x/asp:TextBox>

<asp:Label id="Labe!6" style="Z-INDEX: 110; LEFT: 49px;

POSITION: absolute; TOP: 266px" runat="server">Дoпoлнитeльнaя информация</азр:ЬаЬе1>

<asp:TextBox id="TextBox4" style="Z-INDEX: 111; LEFT: 49px;

POSITION: absolute;

TOP: 295px" runat="server" Width="355px" Height="58px" TextMode="MultiLine"x/asp: TextBox>

<asp:Button id="Buttonl" style="Z-INDEX: 112; LEFT: 49px;

POSITION: absolute;

TOP: 370px" runat="server" Width="130px" Height="24px" Text="noflTBepfl>iTb "X/asp: Button>

</form>

 </body>

</HTML>

Но эта Web-страница пока еще мертва. Необходимо написать исполняемый код для нее. Идеологически все достаточно просто. Требуется собрать введенные данные, а затем подставить их в SQL-запрос insert. Еще раз оговорюсь, что в этой главе не будет рассматриваться синтаксис языка SQL, поэтому достаточно будет лишь напомнить, что этот оператор SQL позволяет добавлять данные в таблицы.

Перед тем, как рассматривать механизм соединения с базой данных и выполнения SQL-запросов, приведем листинг кода, реализующего класс создаваемой Web-страницы. Это листинг 4.2.

 Листинг 4.2

Public Class WebForml

Inherits System.Web.UI.Page

Protected WithEvents Labell As System.Web.UI.WebControls.Label

Protected WithEvents Label2

As System.Web.Ul.WebControls.Label Protected WithEvents TextBoxl

As System.Web.UI.WebControls.TextBox Protected WithEvents Label3

As System.Web.UI.WebControls.Label

Protected WithEvents RadioButtonListl

As System.Web.UI.WebControls.RadioButtonList

Protected WithEvents Label4 As System.Web.UI.WebControls.Label

Protected WithEvents TextBox2 As System.Web.Ul.WebControls.TextBox

Protected WithEvents Labels As System.Web.UI.WebControls.Label

Protected WithEvents TextBox3 As System.Web.Ul.WebControls.TextBox

Protected WithEvents Label6 As System.Web.Ul.WebControls.Label

Protected WithEvents TextBox4 As System.Web.Ul.WebControls.TextBox

Protected WithEvents Buttonl As System.Web.UI.WebControls.Button

#Region " Web Form Designer Generated Code "

'This call is required by the Web Form Designer.

<System.Diagnostics.DebuggerstepThrough()> Private Sub InitializeComponent()

End Sub

Private Sub Page_Init(ByVal sender

As System.Object, ByVal

e As System.EventArgs) Handles MyBase.Init

'CODEGEN: This method call is required by the Web Form Designer

 'Do not modify it using the code editor. InitializeComponent() End Sub

#End Region

Private Sub Page_Load(ByVal sender

As System.Object, ByVal

e As System.EventArgs) Handles MyBase.Load

'Put user code to initialize the page here End Sub

Private Sub Buttonl_Click(ByVal sender

As System.Object, ByVal

e As System.EventArgs) Handles Buttonl.Click

Dim DataConnection As Data.SqlClient.SqlConnection

DataConnection = New Data.SqlClient.SqlConnection ("server=(LOCAL);

uid=sa;

pwd=;

database=Dating")

Dim DataCommand As Data.SqlClient.SqlCommand

Dim InsertCmd As String = "insert into Dating (USNAME, SEX, \ EMAIL, ABOUT, AGE)

values OUsname, @Sex, @Email, gAbout, @Age)"

DataCommand = New Data.SqlClient.SqlCoramand(InsertCmd, DataConnection)

DataCornmand. Parameters .Add (New I Data.SqlClient.SqlParameter("OUsname", System.Data.SqlDbType.NVarChar, ) )

DataCommand.Parameters("@Usname").Value = TextBoxl.Text

DataCommand.Parameters.Add(New fData.SqlClient.SqlParameter("@Sex", System.Data.SqlDbType.Int, 2))

DataCommand.Parameters("@Sex").

Value = RadioButton-;'Listl.SelectedIndex

DataCommand.Parameters.Add(New Data.SqlClient.SqlParameter("@Email", System.Data.SqlDbType.NChar, 50))

DataCommand.Parameters("@Email").Value = TextBox2.Text

DataCommand.Parameters.Add(New

Data.SqlClient.SqlParameter("gAbout", System.Data.SqlDbType.NVarChar, 1000»

DataCommand.Parameters("@About").Value = TextBox4.Text

DataCommand.Parameters.Add(New Data.SqlClient.SqlParameter("@Age", System.Data.SqlDbType.Int, 2))

DataCommand.Parameters("@Age").Value = Val(TextBox3.Text)

DataCommand.Connection.Open()

Try

DataCommand.ExecuteNonQuery()

Response.Redirect("Success.aspx") Catch Exp As Data.SqlClient.SqlException

Response.Redirect("failed.aspx") End Try DataCommand.Connection.Closed

End Sub

End Class

Теперь рассмотрим созданный обработчик нажатия пользователем кнопки. Для работы нам потребуется экземпляр класса Data.sqiciient.sqiconnection, который позволяет устанавливать соединение с SQL-сервером, и экземпляр Класса Data.SqlClient.SqlCommand, позволяющий выполнять SQL-запросы.

После того, как мы объявили экземпляр класса Data.sqiciient.

Sqiconnection с наименованием DataConnection, следует его создать. Для этого мы используем конструктор Data.SqlClient.SqlConnection, котоpому в качестве параметров передается строка, содержащая параметры для установки соединения с базой данных. Из листинга видно, что данная строка состоит из пар "имя=значение", отделенных друг от друга символами точки с запятой. Параметр server позволяет указывать наименование SQL-сервера, к которому производится присоединение. Так как в нашем примере мы используем локальный сервер, который регистрируется в системе автоматически при инсталляции Microsoft SQL Server 2000, то мы используем значение "(LOCAL)".

Затем при помощи параметра uid мы указываем регистрационное имя, под которым происходит присоединение к серверу. Для этого параметра мы используем значение за, которое указывает на встроенную учетную запись администратора. Пароль для этого регистрационного имени указывается при помощи параметра pwd, и в нашем случае этот пароль является пустым. Следует отметить, что подобное подключение к SQL-серверу возможно только в том случае, если тот поддерживает встроенную авторизацию, а не использует авторизацию пользователей, основанную на механизмах идентификации Windows NT. Для того чтобы узнать на какой именно механизм авторизации опирается SQL-сервер, следует в конфигурационной утилите SQL Server Enterprise Manager выделить элемент, соответствующий серверу, и в контекстном меню выполнить команду Edit SQL Server Registration properties (Редактор свойств регистрации SQL-сервера). При этом будет активировано диалоговое окно Registered SQL Server Properties (Свойства регистрации SQL-сервера), показанное на рис. 4.7. В том случае, если действует собственная аутентификация SQL-сервера, должна быть активирована кнопка-переключатель Use SQL Server authentication (Использовать аутентификацию SQL-сервера). Естественно, в этом случае необходимо указать регистрационное имя и пароль для учетной записи, проходящей аутентификацию, в полях Login Name (Регистрационное имя) и Password (Пароль), соответственно.

Примечание

Следует осознавать, что в реальных условиях не следует использовать учетную запись с именем входа " за", так как она общеизвестна, и при определенных условиях злоумышленники могут получить доступ к SQL-серверу, и, воспользовавшись этой учетной записью, полностью изменить структуру баз данных. Поэтому, если нет возможности обойтись без этой встроенной учетной записи, следует установить для нее максимально длинный и сложный пароль. Однако стоит помнить, что любые пароли вскрываемы, поэтому при первой же возможности стоит избавляться от всех учетных записей, устанавливаемых по умолчанию, так как они общеизвестны.

В строке установки соединения также применяется параметр с наименованием Database, в качестве значения которого используется наименование базы данных, к которой мы собираемся подключаться. В нашем случае используется значение Dating.

После того, как было создано соединение с SQL-сервером, следует подготовить для выполнения SQL-запрос. В нашем случае SQL-запрос будет выполнять команду insert, следовательно, никаких наборов данных от этого запроса мы не получим. Для выполнения запроса будет использован экземпляр класса sqicommand. рднако, для него еще необходимо подготовить саму строку, содержащую команду SQL. Для этого используется переменная InsertCmd тип3 String.

В этой строке записывается текст выполняемого SQL-запроса. Так как следует явно указывать значения полей в этой строке, у нас есть два варианта действий. Либо пользуясь данными, введенными пользователем, генерировать эту строку, либо сразу задать текст запроса, но так как нам заранее неизвестны подставляемые значения, воспользоваться параметрами. В нашем примере мы воспользовались вторым способом. При этом строка SQL-запроса приобрела следующий вид:

insert into Dating (USNAME, SEX, EMAIL, ABOUT, AGE)

values (@Usname, @Sex, @Email, @About, 8Age)

Видно, что вместо конкретных значений, сохраняемых в таблице Dating, в строке запроса указаны наименования параметров, начинающиеся с символа @. Для доступа к этим параметрам следует использовать коллекцию Parameters, входящую в состав класса sqicommand. Для каждого параметра мы используем метод Add, который добавляет его в коллекцию. В качестве параметра этому методу передается конструктор класса sqiParameter, который реализует сами параметры SQL-запросов.

Однако перед тем как задать значения этих параметров, следует создать экземпляр класса sgicommand. При этом в качестве параметров передается строка, содержащая текст запроса, и переменная, отвечающая за соединение с SQL-сервером.

В качестве параметров для конструктора класса SqiParameter передаются наименование добавляемого параметра, тип данных, которые будут соответствовать этому параметру, и длина поля, как это показано в листинге.

После того, как все параметры добавлены, следует выполнить подготовленный запрос. Для этого сначала следует открыть подготовленное соединение с SQL-сервером. Поэтому используется метод open, применяемый к свойству Connection, входящему в состав класса sqicoimand. А затем, после того, как соединение открыто, следует выполнить сам SQL-запрос. Для этого мы можем использовать метод ExecuteNonQuery. Однако в нашем примере мы не просто вызываем этот метод, а при помощи конструкции Try ... catch ... End Try подстраховываем себя на случай возникновения каких-либо нештатных ситуаций. В том случае, когда не возникает никаких исключений, пользователь переадресуется на страницу Success.aspx. А если системой было инициировано исключение, пользователь оповещается об этом при помощи переадресации на страницу failed.aspx.

После выполнения запроса следует закрыть соединение при помощи метода close, применяемого к свойству connection, входящему в состав класса sqicommand. На этом работа фрагмента Web-приложения, отвечающего за добавление данных в таблицу, заканчивается. Прежде чем мы перейдем к рассмотрению остальных частей Web-приложения, рассмотрим структуру классов SqlConnection И SqlCommand.

Объект SqlConnection

Объект SqlConnection предназначен для установки соединения с SQL-сервером. В предыдущем разделе мы рассмотрели пример использования его конструктора, но это далеко не все, что следует знать об этом объекте. Тот же самый конструктор может применяться с дополнительными атрибутами, входящими в строку, которая объявляет свойства соединения. Впрочем, аналогичная строка может храниться в свойстве connectionstring, с рассмотрения которого мы и начнем обзор класса SqlConnection.

  • Connectionstring. Свойство типа string, в котором указываются параметры соединения с SQL-сервером. Строка состоит из пар "имя=значение", отделенных друг от друга символами точки с запятой. Естественно, возможные наименования параметров жестко заданы.

Впрочем, необходимо отметить, что большую часть этих параметров можно задать при помощи отдельных свойств.

  • Application Name. Параметр позволяет устанавливать наименование приложения, из которого и устанавливается соединение с SQL-сервером.
  • Connect Timeout или Connection Timeout. Значением этого параметра является целое число, указывающее продолжительность периода в секундах, в течение которого приложение будет ожидать ответа от SQL-сервера на свой запрос. Если в течение этого промежутка SQL-сервер не ответит приложению, соединение будет считаться не установленным. По умолчанию используется значение "15".
  • Connection Lifetime. Это значение позволяет указывать время, в течение которого будет действовать установленное соединение. Значением параметра является целое число, указывающее продолжительность жизни соединения в секундах. По истечении этого промежутка соединение будет принудительно закрыто системой. По умолчанию используется нулевое значение, которое указывает, что соединение имеет неограниченный срок жизни, и его будет закрывать само приложение.
  • current Language. Параметр позволяет указывать язык, на котором написано текстовое содержимое открываемой базы данных.
  • Data source или Server. Параметр позволяет указывать имя SQL-сервера, с которым устанавливается соединение. Если вместо имени необходимо указать сетевой адрес сервера, следует воспользоваться
  • параметрами Address, Addr или Network Address.
  • Database или initial Catalog. Параметр указывает наименование базы данных, к которой происходит подключение.
  • Trusted_Connection или Integrated Security. Параметр позволяет указывать, что соединение будет устанавливаться по защищенному каналу. В качестве значений могут использоваться ключевые слова true или false. Если используется значение по умолчанию false, соединение устанавливается без соблюдения особых правил безопасности. Впрочем, в тех случаях, когда и SQL-сервер, и приложение находятся на одной и той же машине, нет смысла использовать защищенное соединение.
  • Max Pool size. Значением этого параметра является число, указывающее максимальное количество соединений, которое может одновременно поддерживать SQL-сервер. По умолчанию используется значение "100".
  • Min Pool size. Значением этого параметра является число, указывающее минимальное количество соединений, которое может одновременно поддерживать SQL-сервер. По умолчанию используется нулевое значение.
  • Password или Pwd. Параметр указывает пароль для регистрационного имени, под которым происходит соединение с базой данных.
  • user id. Параметр позволяет указывать регистрационное имя, под которым происходит соединение с базой данных.
  • connectionTimeout. Свойство типа integer. Свойство устанавливает продолжительность в секундах периода тайм-аута при соединении с базой данных. По умолчанию используется значение "15".
  • Database. Свойство типа string. В нем указывается наименование базы данных, к которой и присоединяется приложение.
  • DataSource. Свойство типа string. В нем указывается наименование, под которым зарегистрирован SQL-сервер, к которому присоединяется приложение.
  • Packetsize. Свойство типа integer, в котором указывается размер (в байтах) пакетов информации, пересылаемых от приложения к серверу и обратно. Значение свойства может находиться в пределах от 512 до 32767. По умолчанию используется значение "8192".
  • Serverversion. Свойство типа string, в котором отображается номер версии сервера, с которым устанавливается соединение.

Теперь перейдем к рассмотрению методов класса sgiconnection.

  • BeginTransaction. Метод вызывает запуск транзакции. Если использовать метод без параметров, то будет применена стандартная транзакция, запускаемая по умолчанию. Однако в качестве параметра можно передать строку, содержащую наименование транзакции. О работе с транзакциями будет более подробно рассказано в одном из следующих разделов этой главы.
  • ChangeDatabase. Метод позволяет изменить наименование базы данных, к которой при помощи объекта sqiconnection было присоединено приложение. В качестве параметра типа string методу передается наименование базы данных, к которой будет подключено текущее соединение.
  • close. Метод закрывает соединение.
  • CreateCommand. Метод позволяет создать экземпляр класса SqlCommand, который будет связан с открытым соединением.
  • open. Метод позволяет открыть соединение. При этом метод использует свойство Connectionstring для получения параметров открываемого соединения.
  • На этом мы заканчиваем рассмотрение структуры класса sqiconnection и переходим к рассмотрению класса SqlCommand.

    Объект SqICommand

    Объект Sqicommand реализует SQL-запросы в рамках приложений. В одном из предыдущих разделов этой главы мы уже наблюдали пример использования этого объекта, а сейчас пришло время несколько внимательнее рассмотреть его структуру.

    Этот объект обладает четырьмя конструкторами. В простейшем случае метод-конструктор не обладает параметрами и основные параметры созданного экземпляра класса придется задавать при помощи свойств. Однако разработчик может сразу при создании экземпляра класса указать строку, содержащую текст SQL-запроса, соединение, в рамках которого будет действовать этот запрос, и транзакцию. Так что программист может выбрать именно тот конструктор, который будет наиболее хорошо удовлетворять его требованиям.

    А теперь перейдем к рассмотрению свойств и методов класса Sqicommand.

    • CommandText. Свойство типа string, содержащее текст SQL-запроса, связанного с данным экземпляром класса Sqicommand.
    • CommandTimeout. Свойство типа integer, задающее продолжительность периода тайм-аута для искомого запроса в секундах.
    • commandType. Свойство указывает, какой именно запрос находится в свойстве CommandText, а точнее, тип запроса. Значение должно входить в состав перечислимого типа CommandType. Все возможные значения перечислены ниже.
    • storedProcedure. Текст является наименованием хранимой процедуры.
    • TabieDirect. Текст является наименованием таблицы. Это значение используется только для OLE DB .NET Data Provider.
    • Text. Текст обычного SQL-запроса.
    • Connection. Свойство типа sqiconnection. В нем содержится соединение с сервером, при помощи которого и выполняется SQL-запрос.
    • П
    • Parameters. Свойство типа SqlParameterCollection, который является коллекцией, обеспечивающей доступ к параметрам SQL-запроса.
    • Transaction. Свойство типа sqiTransaction, содержащее транзакцию, в рамках которой выполняется SQL-запрос.

    Теперь перейдем к рассмотрению методов, входящих в состав данного класса.

    • cancel. Метод принудительно обрывает выполнение SQL-запроса.
    • createParameter. Метод создает параметр SQL-запроса. В качестве результата своей работы метод возвращает значение типа SqiParameter.
    • ExecuteNonQuery. Метод применяется для выполнения SQL-запросов, которые не возвращают какие-либо наборы данных. Обычно подобные запросы базируются на ключевых словах Update, insert или Delete.
    • Prepare. Метод подготавливает SQL-запрос к выполнению. Если один и тот же запрос выполняется несколько раз, стоит воспользоваться этим методом. При "подготовке" запроса, его последующее выполнение производится несколько быстрее.
    • ResetcommandTimeout. Этот метод сбрасывает продолжительность периода тайм-аута для SQL-запроса до значения, используемого по умолчанию.

    Итак, мы рассмотрели структуру объекта sqicommand и можем переходить к рассмотрению иных технологий работы с базой данных.

    Поиск и отображение информации

    Вернемся к нашему проекту сайта знакомств. Мы уже создали страницу, при помощи которой посетитель сайта может внести в базу данных информацию о себе. Теперь необходимо реализовать поиск по этой базе.

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

    Естественно, поиск данных будет производиться при помощи SQL-запроса, основанного на ключевом слове select. Однако здесь следует сделать некоторое отступление. В предыдущем примере мы использовали SQL-запрос, который не возвращал каких-либо данных. SQL-запрос select обязательно будет возвращать некоторое множество записей из основной таблицы. Это множество записей будет являться источником данных для Web-страницы, показывающей результат запроса пользователя. Подобные источники данных в ASP.NET реализуются при помощи типа DataSet. Его структуру мы рассмотрим в следующем разделе главы, а в этом разделе мы просто приведем пример его использования.

    Итак, для начала необходимо спроектировать Web-страницу, на которой пользователь будет указывать критерии поиска по базе данных. Эту страницу мы назовем search.aspx. Затем, все введенные данные будут переданы Web-странице с наименованием bind.aspx. При загрузке этой страницы будет сформирован запрос select, опираясь на критерии пользователя. Затем этот запрос будет выполнен, и его результаты будут отображены в таблице.

    Так как наша база данных очень невелика, то и критериев поиска будет немного. Мы предоставим пользователю возможность указать пол пользователей при помощи группы переключателей. В листинге 4.3 приведен HTML-код страницы в режиме ее разработки.

    Лисгинг 4.3

    <%@ Page Language="vb" AutoEventWireup="false" Codebehind="search.aspx.vb" Inherits="dating. search"%>

    lDOCTYPE HTML PUBLIC "-//W3C//DTD

    HTML 4.0 Transitional//EN">

    <HEAD>

    <titlex/title>

    <meta content="Microsoft Visual Studio. NET 7.0" name=" GENERATOR ">

    <meta content="Visual Basic 7.0" name="CODE_LANGUAGE">

    <meta content=" JavaScript" name="vs_defaultClientScript">

    ta content="http: //schemas .microsoft.com/intellisense/ie5"

    "vs targetSchema">

     

    </HEAD>

     <body MS POSITIONING="GridLayout">

    <form id="Forml" method="post" runat="server">

    <asp: label id="Labell" style="Z-INDEX: 101; LEFT: 41px;

    POSITION: absolute;

    TOP: 20px" runat=" server" Height="19px" Width="196px">Укaжитe критерии поиска</азр: label>

    <asp: label id="Labe!2" style="Z-INDEX: 102; LEFT: 41px;

    POSITION: absolute;

    TOP: 51px" runat="server">nc^</asp: label>

    <asp:radiobuttonlist id="RadioButtonListl" style="Z-INDEX: 103; LEFT: 41px;

    POSITION: absolute;

    TOP: Slpx" runat="server">

    <asp:List!tem Value="0" Selected="True">Myжcкoй</asp:ListItem>

    <asp:List!tem Value="l">Жeнcкий</asp:ListItem>

    </asp: radiobuttonlist>

    <asp:button id="Buttonl" style="Z-INDEX: 109; LEFT: 44px;

     POSITION: absolute;

    TOP: 140px" runat=" server" Height="24px" Width="120px" Text= "Искать ! ">

    </asp:button>

    </form>

    </body>

    </HTML>

    При нажатии на кнопку Искать! пользователь должен быть направлен на другую Web-страницу, которая и будет производить поиск. Поэтому обработчик нажатия кнопки будет достаточно прост. Полный код класса, реализующего созданную Web-страницу, приведен в листинге 4.4.

    Листинг 4.4

    Public Class search

    Inherits System. Web. UI . Page

    Protected WithEvents Label2 As System. Web. UI .WebControls .Label

    Protected WithEvents RadioButtonListl

    As System.Web.UI.WebControls.RadioButtonList

    Protected WithEvents Label3

    As System.Web.UI.WebControls.Label Protected WithEvents Label4

    As System.Web.UI.WebControls.Label Protected WithEvents Label5

    As System.Web.UI.WebControls.Label Protected WithEvents TextBoxl

    As System.Web.UI.WebControls.TextBox Protected WithEvents TextBox2

    As System.Web.UI.WebControls.TextBox Protected WithEvents Buttonl

    As System.Web.UI.WebControls.Button Protected WithEvents Labell

    As System.Web.UI.WebControls.Label

    #Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.

    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub

    Private Sub Page_Init(ByVal sender As System.Object, ByVal

    e As System.EventArgs) Handles MyBase.Init

    'CODEGEN: This method call is required by the Web. Form Designer

    'Do not modify it using the code editor. InitializeComponent() End Sub

    #End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal

    e As System.EventArgs) Handles MyBase.Load

    'Put user code to initialize the page here End Sub

    Private Sub Buttonl_Click(ByVal sender As System.Object, ByVal

    e As System.EventArgs) Handles Buttonl.Click

    Session.Add("sex", RadioButtonListl.Selectedlndex) Response.Redirect("bind.aspx")

    End Sub

    End Class

    Видно, что при нажатии пользователем кнопки, информация, введенная им, передается на следующую страницу при помощи стандартной коллекции Объекта Session.

    Теперь рассмотрим процедуру создания Web-страницы, которая будет осуществлять поиск и отображение его результатов. Для отображения результатов поиска мы будем использовать компонент DataGrid, который позволяет отображать таблицу, связанную с каким-либо набором данных. Этот компонент имеет множество настроек внешнего вида, которые могут устанавливаться в визуальном режиме. Для этого в контекстном меню компонента следует выполнить команду Property Builder (Построитель свойств), и будет отражено диалоговое окно, в котором и следует устанавливать свойства. однако, наша задача сейчас не украсить таблицу, а добиться того, чтобы ней отображались результаты поиска. Поэтому оставим компонент в том , как он создается по умолчанию. В листинге 4.5 показан HTML-код задаваемой Web-страницы в режиме разработки.

    Листинг 4.5

    <%@ Page Language="vb" AutoEventWireup="false" Codebehind="bind.aspx.vb" jplnherits="dating.bind"%>

    <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

    <HTML>

    <HEAD>

    <titlex/title>

    <meta content="Microsoft Visual Studio.NET 7.0" name="GENERATOR">

    <meta content="Visual Basic 7.0" name="CODE_LANGUAGE">

    <meta content="JavaScript" name="vs_defaultClientScript">

    <meta content="http: //schemas.microsoft.com/intellisense/ie5" 1 name="vs_targetSchema">

    </HEAD>

    <body MS_POSITIONING="GridLayout">

    <form id="Forml" method="post" runat="server">

    <asp:datagrid id="DataGridl" style="Z-INDEX: 101; LEFT: 28px;

    POSITION: absolute;

    TOP: 22px" runat="server" Height="165px" Width="348px" ShowHeader="False"x/asp:datagrid>

    </form>

    </body>

    </HTML>

    А теперь, после того, как мы увидели HTML-код страницы, следует привести исполняемый код ее класса. Он показан в листинге 4.6.

    Листинг 4.6

    Public Class bind

    Inherits System.Web.UI.Page

    Protected WithEvents DataGridl

    As System.Wet^UI.WebControls.DataGrid

    #Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.

    <System.Diagnostics.DebuggerstepThrough()> Private Sub InitializeComponent()

    End Sub

    Private Sub Page_Init(ByVal sender

    As System.Object, ByVal

    e As System.EventArgs) Handles MyBase.Init

    'CODEGEN: This method call is required by the Web Form Designer

     'Do not modify it using the code editor. InitializeComponent() End Sub

    #End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal

    e As System.EventArgs) Handles MyBase.Load

    'Put user code to initialize the page here

    Dim DS As DataSet

    Dim DataConnection As Data.SqlClient.SqlConnection

    Dim DataCommand As Data.SqlClient.SqlDataAdapter

    Dim SelectCommand As String = "select USNAME, EMAIL, ABOUT, AGE from Dating where (SEX = @Sex)"

    DataConnection = New

    Data.SqlClient.SqlConnection("server=(LOCAL); _ uid=sa;pwd=;database=Dating")

    DataCommand = New Data.SqlClient.SqlDataAdapter(SelectCommand, DataConnection)

    DataCommand.SelectCommand.Parameters.Add(New Data.SqlClient.SqlParameter("8Sex", System.Data.SqlDbType.Int, 2))

    DataCommand.SelectCommand.Parameters("@Sex").Value = Session.Itern("sex")

    DS = New DataSet() DataCommand.Fill(DS, "Dating")

    DataGridl.DataSource = DS DataGridl.DataBind()

    End Sub

    End Class 

    Этот код следует детально рассмотреть. Поиск и отображение результатов происходят при загрузке Web-страницы, поэтому мы используем обработчик события page_Load. Также нам потребуется по одному экземпляру трех раз-S личных объектов. Мы используем уже знакомый нам объект sqiconnection f для установки соединения с базой данных, объект sqiDataAdapter, который I предназначен для выполнения SQL-запроса и получения данных из таблицы, а также объект DataSet, который и получит извлеченные данные, а затем послужит источником данных для таблицы. Также в процедуре объявля- 1 ется переменная seiectcommand типа string. В этой переменной будет /храниться текст -SQL-запроса select. Следует отметить, что в этом запросе также используется один параметр.

    После того, как объявлены все переменные, создается соединение с базой сданных при помощи конструктора класса sqiconnection. Затем в коллекцию параметров запроса добавляется параметр целочисленного типа. С помощью следующего оператора этому параметру присваивается значение, которое хранилось в элементе коллекции объекта Session. После этого ''Выполняется метод Fill переменной DataCommand. В качестве параметров методу передается переменная типа DataSet и наименование таблицы, из которой извлекаются данные. Этот метод заполняет набор данных DS. Осталось только соединить полученный набор данных с таблицей DataGridl.

    Соединение набора данных с таблицей происходит при помощи свойства DataSource, присущего компоненту DataGrid. А после того, как источник данных для таблицы задан, необходимо отобразить данные в ней. Для этого мы используем метод DataBind. В результате, после запроса пользователя, все записи из базы данных, удовлетворяющие условию, будут отображены в таблице. Внешний вид этой Web-страницы показан на рис. 4.1.

    Рис. 4.1. Web-страница с отображением результатов запроса

    HTML-код этой страницы приведен в листинге 4.7.

    Листинг 4.7

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

    <HTML>

    <HEAD>

    <title>

    </title>

    <meta content="Microsoft Visual Studio.NET 7.0" name="GENERATOR">

    <meta content="Visual Basic 7.0" name="CODE_LANGUAGE">

    <meta content="JavaScript" name="vs_defaultClientScript">

    cmeta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">

    </HEAD>

    <body MS_POSITIONING="GridLayout">

    <form name="Forml" method="post" action="bind.aspx" id="Forml">

    <table cellspacing="0" rules="all" border="l" id="DataGridl" style="height:165px;width:348px;

    border-collapse:collapse;Z-INDEX: 101; LEFT: 28px;

    POSITION: absolute;

    TOP: 22px">

    <tr>

    <td>

    Татьяна

    </tdxtd>

    tanya@mail.ru </tdxtd>

    У меня серые глаза

    </tdxtd>

    22

    </td>

    </trxtr>

    <td>

    Елена

    </tdxtd>

    lena@mail. ru </tdxtd>

    Я олично готовлю

    </td>

    <td>

    31

    </td>

    </tr>

    <tr>

    <td>

    Светлана

    </tdxtd>

    svetagmail.ru

    </tdxtd>

    Натуральная блондинка

    </td>

    <td>

    19

    </td>

    </tr>

    <tr>

    <td>

    Вера

    </td>

    <td>

    vera@mail.ru

    </tdxtd>

    А я не знаю, что про себя рассказать </tdxtd>

    24

    </td>

    </tr>

    </table>

    </form>

    </body>

    </HTML>

    В следующем разделе главы мы рассмотрим структуру объекта Dataset, который позволяет хранить наборы данных и отображать их на Web-страицах, а пока укажем еще на одну интересную возможность компонента DataGrid.

    В нашем примере таблица не заняла много места на Web-странице. Но ведь Далеко не всегда объемы получаемых данных будут настолько малы, что их можно будет разместить на одной Web-странице. В тех случаях, когда таблица получается слишком большая, ее можно разбить на несколько страниц. Для этого необходимо в режиме разработки страницы выполнить для объекта DataGrid команду контекстного меню Property Builder (Построитель свойств). На отображенном диалоговом окне следует выбрать вкладку Paging (Разбиение на страницы).

    Для того чтобы таблицу можно было разбивать на несколько частей, каждая из которых отображалась бы на отдельной Web-странице, следует поставить флажок в независимом переключателе Allow paging (Разрешить разбиение на страницы). После этого разработчик получает доступ ко всем остальным органам управления, расположенным на этой вкладке.

    Прежде всего, следует указать, сколько строк таблицы будет размещаться на одной странице. Это количество строк указывается в поле Page size (Размер страницы). Для того чтобы пользователь мог перемещаться между страницами, на которых расположена таблица, следует отображать кнопки перехода между страницами. Активация этих кнопок произойдет, если в диалоговом окне отметить флажок в независимом переключателе Show navigation buttons (Показать кнопки управления). Расположение кнопок управления между страницами регулируется при помощи пунктов выпадающего списка Position (Расположение). А текст надписей на этих кнопках указывается в полях текстового ввода Next Page Button Text (Кнопка текста следующей страницы) и Previous Page Button Text (Кнопка текста предыдущей страницы).

    Итак, мы рассмотрели способы отображения информации из базы данных в таблице. Теперь следует ознакомиться со структурой объекта sqiDataAdapter.

    Объект SqiDataAdapter

    Объект SqiDataAdapter предназначен для выполнения некоторых команд, которые позволяют заполнять данными объекты типа Dataset. В предыдущем разделе мы видели в приведенном примере, как при помощи экземпляра класса SqlDataAdapter создавался и выполнялся параметрический SQL-запрос, а затем результаты его выполнения перенаправлялись в набор данных Dataset. Таким образом, мы можем с полной уверенностью сказать, что в Web-приложениях объект SqlDataAdapter чаще всего будет использоваться именно для связи SQL-запросов как команда с отображаемыми результатами этих запросов. А теперь начнем рассмотрение свойств структуры класса SqlDataAdapter.

    • DeieteCommand. Свойство типа Sqicommand, которое мы рассматривали в этой главе несколько ранее. В этом свойстве хранится SQL-запрос, основанный на ключевом слове delete, т. е. предназначенный для удаления одной или нескольких записей из базы данных.
    • insertcommand. Свойство типа Sqicommand. В нем хранится SQL-запрос, основанный на ключевом слове insert, т. е. предназначенный для добавления записи в базу данных.
    • Seiectcoitmand. Свойство типа Sqicommand. В этом свойстве находится стандартный SQL-запрос выбора информации из базы данных, основанный, естественно, на ключевом слове select.
    • updateCommand. Свойство типа Sqicommand. В нем хранится SQL-запрос, основанный на ключевом слове update, т. е. предназначенный для изменения одной или нескольких записей в базе данных.

    Как видно, основные свойства рассматриваемого объекта SqlDataAdapter предназначены для хранения различных SQL-запросов. Другими словами, рдному экземпляру объекта может соответствовать несколько SQL-запросов различного типа, каждый из которых может быть применен в зависимости от ситуации. Но для выполнения SQL-запросов следует использовать все-таки методы объекта. Рассмотрим и их.

    • Fin. Это один из наиболее часто используемых методов объекта SqlDataAdapter. Предназначен для заполнения набора данных DataSet или объектов со схожей функциональностью. Метод существует в различных модификациях, отличающихся друг от друга только набором передаваемых параметров. Чаще всего в качестве параметра передается либо экземпляр объекта DataSet, либо комбинация этого экземпляра и строки, в которой указывается наименование таблицы, из которой извлекаются данные для занесения в экземпляр DataSet. При этом используется SQL-запрос, хранящийся В Свойстве SelectCommand.
    • update.
    • Метод применяется для выполнения SQL-запросов, хранящихся В свойствах DeieteCommand, InsertCommand И UpdateCommand. В качестве параметров методу обычно передается либо экземпляр DataSet, либо таблица, к которой будут применяться эти SQL-выражения. Естественно, если какое-либо из перечисленных свойств экземпляра класса sqioataAdapter не будет заполнено, то и соответствующий этому свойству SQL-запрос не будет выполняться.

    Итак, при помощи этих двух методов мы можем выполнить любой SQL-запрос и применить его к экземпляру класса Dataset. А уже экземпляр класса Dataset мы можем использовать в качестве источника данных для компонентов Web Forms, размещаемых на разрабатываемых Web-страницах.

    Таким образом, разработчик получает в свое распоряжение стройную иерархию объектов, которые позволяют устанавливать соединение с базой данных, извлекать данные из нее и модифицировать саму базу данных, а потом сделанную выборку отображать на Web-страницах.

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

    Использование рассмотренных нами компонентов в идеологии Microsoft называется ADO.NET. ADO расшифровывается как AciveX Data Object. Рассмотрим эту концепцию в следующем разделе главы.

    ADO.NET

    После того, как на протяжении целой главы рассматривалась некая технология работы с базами данных, попробуем подвести под нее теоретическую базу. Как было сказано в предыдущем разделе, использованная нами технология носит наименование ADO.NET. Она является наследником технологии ADO (ActiveX Data Object). Если в предыдущей версии ADO упор делался на создании постоянных соединений, то в ADO.NET, ориентированной, как это видно из названия, на работу в сетях, по умолчанию создаются соединения, не поддерживаемые в подключенном состоянии все время.

    Как мы уже знаем, одним из объектов ADO.NET, наиболее близким к компонентам Web Forms является Dataset. Объект Dataset может хранить в себе не только набор записей, а различные таблицы, связи их друг с другом, отдельные поля и прочую атрибутику баз данных. При этом Dataset не взаимодействует напрямую с источником данных. В рассмотренных примерах было показано, как для заполнения объектов Dataset были использованы объекты промежуточного звена. Одним из таких объектов являлся класс SqlDataAdapter.

    Следует также отметить, что в качестве источника данных для объекта Dataset могут быть использованы не только стандартные базы данных, но и XML-файлы. Однако, в наших примерах, приведенных в данной главе, мы использовали в качестве основного SQL-сервера Microsoft SQL Server 2000. Но Web-приложения, созданные на базе ASP.NET, могут использовать любую базу данных, для которой есть соответствующий ODBC-драйвер.

    И вот здесь следует сделать некоторое отступление. В ADO.NET информацию из баз данных могут предоставлять два типа источников данных — SQL iManaged Provider и ADO Managed Provider. Источник данных SQL Managed Jfrovider предоставляет доступ к базам данных, обслуживаемым серверами fMicrosoft SQL Server 7.0 и Microsoft SQL Server 2000. Для всех остальных баз данных используется источник данных ADO Managed Provider.

    Следует отметить, что источник данных SQL Managed Provider обеспечивает несколько большую скорость работы, нежели его собрат ADO Managed Provider, поэтому если есть возможность, следует использовать для работы SQL-серверы от Microsoft, начиная с седьмой версии.

    Естественно, все объекты для этих двух типов источников данных имеют одинаковые наименования и практически одинаковую функциональность. Различие лишь в том, что все объекты, принадлежащие SQL Managed Provider, располагаются в пространствах имен System.Data и System.Data.SQL, а их функциональные двойники, работающие в сфере ADO Managed Provider, располагаются в пространствах имен System.Data и System.Data.ADO. Таким образом, если разработчику необходимо использовать СУБД, доступ к которой осуществляется при помощи драйвера ODBC, ему следует использовать два последних пространства имен, а сами объекты останутся теми же самыми.

    Чаще всего для взаимодействия Web-страниц с базой данных используются три компонента — connection, command и DataSet. Эта триада практически идеально подходит для использования в Web-приложениях, которые логически разделены на несколько слабосвязанных частей (каждая часть соответствует одной Web-странице), когда нельзя заранее предсказать, какое именно действие произведет пользователь и какой блок данных потребуется ему. Поэтому модель краткосрочных соединений и иерархия Соединение — Команда — Набор данных позволяют при наименьших затратах ресурсов добиться максимальной производительности и свободы действий для разработчика.

    Итак, в этой главе мы рассмотрели вопросы работы Web-приложений ASP.NET с базами данных. Несомненно, рассмотренные нами примеры охватывают лишь начальные этапы работы, так как функциональность объектов ADO.NET позволяет создавать и обрабатывать гораздо более сложные структуры данных, однако в рамках книги мы свою задачу выполнили и можем двигаться дальше. На очереди — извлечение данных из XML-файлов.

    Извлечение данных из XML-файлов

    О самом языке XML будет достаточно подробно рассказано в следующей главе. Однако в процессе изложения материала мы уже сталкивались с файлами XML, поэтому сможем использовать их в достаточно простом примере.

    Итак, как нам уже известно, файлы XML являются простыми текстовыми файлами, имеющими такую же структуру, как и HTML-файлы, но при этом набор используемых тегов определяет сам разработчик. Естественно, подобная структура позволяет хранить в XML-файлах не только структурированные тексты, но и информацию из баз данных. Естественно, XML никогда не сможет заменить стандартные механизмы систем управления базами данных, однако при использовании определенных выборок данных для Web эти файлы могут быть полезны. Достаточно всего лишь настроить параметры отображения XML-файлов в браузере пользователя, и можно передавать ему весь файл как есть, без дополнительной обработки.

    Впрочем, иногда дополнительная обработка может понадобиться, но стоит вспомнить, что технология Microsoft .NET очень плотно связана с XML, поэтому в ней присутствуют средства достаточно прозрачной работы с XML-файлами. В рамках этого раздела мы, естественно, не сможем рассмотреть всю технологию использования XML в проектах ASP.NET, для этого пришлось бы писать отдельную книгу, но мы рассмотрим механизм использования XML-файла в качестве источника данных для таблицы, отображаемой на Web-странице.

    Для начала нам придется создать простейший XML-файл, содержащий какую-либо информацию. Код этого файла приведен в листинге 4.8.

    Листинг 4.8

    <Document> <Row>

    <Coluiml>K/Columnl>

    <Column2>2</Column2>

    <Column3>3</Column3>

    <Column4>4</Column4>

    </Row>

    <Row>

    <Columnl>5</Coluitml>

    <Coluim2>6</Column2>

    <Column3>7</Column3>

    <Column4>8</Column4>

    </Row>

    </Document>

    Как видно, структура и содержимое XML-файла максимально прозрачны. Для простоты доступа этот файл стоит разместить в том же каталоге, в котором будет функционировать создаваемое Web-приложение. Впрочем, это не критично.

    Теперь перейдем к созданию самого Web-приложения. На разрабатываемой Web-странице достаточно будет разместить один компонент DataGrid. HTML-код этой Web-страницы в режиме разработки приведен в листинге 4.9.

    Листинг 4.9

    <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForml.spx.vb" jnherits="dataxml.WebForml"%>

    felDOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

    < HTML>

    <HEAD>

    <title>

    </title>

    <meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">

    <meta name="CODE__LANGUAGE" content="Visual Basic 7.0">

    <meta name="vs_defaultClientScript" content="JavaScript">

    <meta name="vs_targetSchema"

    Rcontent="http://schemas.microsoft.com/intellisense/ie5">

    </HEAD>

    <body MS_POSITIONING="GridLayout">

    <form id="Forml" method="post" runat="server">

    <asp:DataGrid id="DataGridl" style="Z-INDEX: 101; LEFT: ЗОрх;

    POSITION: absolute;

    TOP: 13px" runat="server" Width="282px"

    Height="162px"x/asp:DataGrid>

    </form>

    </body>

    </HTML>

    Естественно, это не самый сложный листинг, который приходилось нам I рассматривать в этой книге. Но вот код класса, который будет считывать данные из XML-файла и помещать их в таблицу, будет несколько сложнее. Этот код приведен в листинге 4.10.

    Л истинг 4.10

    Public Class WebForml "i Inherits System.Web.HI. Page

    Protected WithEvents DataGridl

    As System.Web.UI.WebControls.DataGrid

    #Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.

    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub

    Private Sub Page_Init(ByVal sender

    As System.Object, ByVal

    e As System.EventArgs) Handles MyBase.Init

    'CODEGEN: This method call is required by the Web Form Designer

    'Do not modify it using the code editor. InitializeComponent()

    End Sub

    #End Region

    Private Sub Page_Load(ByVal sender

    As System.Object, ByVal

    e As System.EventArgs) Handles MyBase.Load

    'Put user code to initialize the page here

    Dim DS As New DataSet()

    Dim FS As 10.FileStream

    Dim Reader As lO.StreamReader

    FS = New IO.FileStream(Server.MapPath("datal.xml"), IO.FileMode.Open, 10.FileAccess.Read)

    Reader = New lO.StreamReader(FS) DS.ReadXml(Reader) FS.Close ()

    Dim Source As DataView Source = New DataView(DS.Tables(0))

    DataGridl.DataSource = Source DataGridl.DataBind()

    End Sub

    End Class

    Как видно, все операции будут выполняться в обработчике загрузки таблицы. Нам потребуется один экземпляр класса DataSet, переменная fs, которая позволяет работать с файлами, и переменная Reader, предназначенная для чтения потоков информации из файла.

    Файл datal.xml открывается в конструкторе объекта FileStream, причем, как легко заметить, открывается только на чтение. Затем при помощи метода Readxmi мы считываем данные из потока, связанного с XML-файлом. Этого достаточно. Теперь все данные уже находятся в экземпляре объекта DataSet. Затем, мы объявляем переменную типа DataView, которая обраща- ется к начальному элементу коллекции Tables из созданного набора данных. Как мы уже знаем, в объектах DataSet может храниться несколько таблиц сразу, но в данном случае, там точно всего одна таблица, поэтому можно смело применить начальный и единственный элемент коллекции Tables. A затем эту извлеченную таблицу мы используем в качестве источника данных для компонента DataGridi и отдаем команду на отображение полученных данных при помощи метода DataBind. В результате этих действий браузере отображается Web-страница, внешний вид которой показан на рис. 4.2.

    Следует обратить внимание на то, с какой легкостью мы подключили XML-файл к таблице без какого-либо описания данных. Вся прелесть механизма JASP.NET в том, что он автоматически распознает структуру корректных XML-файлов и может отлично их обрабатывать.

    Рис. 4.2. Внешний вид Web-страницы, на которой отображаются данные из XML-файла

    Итак, на этом мы заканчиваем рассмотрение работы с данными для Web-приложений в рамках технологии ASP.NET. Настало время несколько внимательнее рассмотреть язык XML. Этому и будет посвящена следующая глава.



    Опубликовал admin
    23 Авг, Понедельник 2004г.

    Комментарии

    здравствуйте. подскажите пожалуйста что делать при такой ошибке
    Parser Error

    Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

    Parser Error Message: Could not load type 'search.dating'.

    Source Error:

    Line 1: <%@ Page Language="vb" AutoEventWireup="false" Codebehind="search.aspx.vb" Inherits="search.dating" %>
    Line 2:
    Line 3:

    Source File: /search.aspx Line: 1

    Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
    заранее спасибо




    Программирование для чайников.