Опубликован: 25.09.2008 | Доступ: свободный | Студентов: 3223 / 516 | Оценка: 4.32 / 3.98 | Длительность: 18:50:00
ISBN: 978-5-94774-991-5
Лекция 10:

Использование баз данных в приложениях ASP.NET

< Лекция 9 || Лекция 10: 12345678910

Отсоединенные наборы данных

Рассмотренная ранее логика взаимодействия клиентского приложения с базой данных, основанная на соединении, оправдана для реализации односторонней связи с базой данных. Это может быть либо получение данных, либо выполнение запросов, связанных с внесением изменений в нее. Реализация же сложных операций взаимодействия с БД при этом является очень трудоемким процессом и требует написания большого количества программного кода, его отладки и т. д. ADO.NET предоставляет более совершенные способы организации двустороннего взаимодействия приложения с базой данных, основанной на отсоединенных наборах данных.

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

Класс DataSet

Объект DataSet представляет собой контейнер, содержащий объекты DataTable и Relation. DataTable представляет собой таблицу, состоящую из строк и столбцов. Строки таблицы представлены объектом DataRow, который, в свою очередь, представляет собой коллекцию столбцов таблицы (объект DataColumn ). Данные в DataSet отсоединены от БД. Все изменения данных кэшируются в объектах DataRow. При возникновении необходимости передачи изменений в данных объекта DataSet существует возможность передачи только изменившейся части данных, что позволяет значительно экономить ресурсы канала связи, т. к. в этом случае передается гораздо меньший объем данных. Обобщая все вышесказанное, можно сделать вывод о том, что использование объекта DataSet в ряде случаев оказывается более эффективным, чем DataReader. Наиболее типичными ситуациями, в которых рекомендуется применять объект DataSet, являются следующие:

  1. Необходимость реализации сериализации данных на диск. DataSet позволяет легко сохранять данные в файле XML. При этом возможны варианты сохранения либо только данных, либо только структуры данных, либо и того и другого.
  2. Необходимость организации навигации по набору данных в двух направлениях. Как уже упоминалось, DataReader обеспечивает перемещение по набору только вперед. С помощью же DataSet возможна организация постраничного просмотра данных.
  3. Необходима привязка нескольких элементов управления к одному набору данных. DataSet, в отличие от DataReader, содержит средства организации сортировки и фильтрации данных.

Более подробная информация относительно сценариев использования DataSet находится в [ 1 ] .

Важно! Большинство Web-приложений использует DataSet для извлечения данных из базы данных и показа их на странице. Для обновления же данных в БД используются прямые команды.

Использование DataSet

Выше уже говорилось о том, что DataSet состоит из таблиц, которые, в свою очередь, состоят из строк, а они, в свою очередь, - из столбцов. Каждый из перечисленных элементов реализован в виде класса. Для управления автономными изменениями DataSet отслеживает информацию о версии каждого объекта DataRow. Это означает, что когда происходит редактирование строки, ее исходное значение сохраняется в памяти, а строка помечается как измененная. Аналогичные действия происходят и при добавлении и изменении строк DataTable. В дальнейшем в базу данных можно перенести значения только тех строк, которые были затронуты изменениями. Таким образом, DataSet никогда не поддерживает постоянного соединения с базой данных.

Для извлечения данных из базы данных и наполнения ими объекта DataSet необходимо использовать еще один объект DataAdapter, который помимо прочего позволяет обновлять данные БД на основе внесенных в DataSet изменений.

Класс DataAdapter

DataAdapter является связующим звеном между базой данных и DataSet. Точнее, он связывает БД и объект DataTable, расположенный внутри DataSet.

DataAdapter содержит три основных метода, которые позволяют ему выполнять все необходимые операции, связанные с извлечением и обновлением данных.

Fill Выполнение запроса типа Select, определенного в свойстве SelectCommand, и добавление таблицы, получаемой в результате данного запроса, в DataSet.
FillSchema() Выполнение запроса типа Select, текст которого расположен в свойстве SelectCommand, и добавление таблицы, которая содержит только структуру данных, полученных в результате выполнения запроса, в DataSet.
Update() Применяет все изменения, внесенные в DataTable, к источнику данных. При этом исполняются команды вставки, обновления и удаления, расположенные в свойствах InsertCommand, UpdateCommand, DeleteCommand.

Рассмотрим пример использования объектов DataSet и DataAdapter для извлечения данных из БД, наполнения DataSet и отображения данных на странице Web-приложения.

Прежде всего, необходимо установить подключение к источнику данных. Для этого нужно использовать строку подключения, а также объект Connection. В данном примере подключение будет происходить к базе данных Test_Db, расположенной на локальном сервере SQL Server Express 2005:

string strCon = "Server=.\SQLEXPRESS;Integrated
 Security=SSPI;Initial Catalog=Test_Db";
string sqlString = "SELECT * FROM Товары";
SqlConnection sqlCon = new SqlConnection(strCon);

Создадим объект DataAdapter и передадим ему в качестве параметров строку запроса, а также строку подключения к БД:

SqlDataAdapter da = new SqlDataAdapter(sqlString,sqlCon);

Теперь необходимо создать объект DataSet и заполнить его данными с помощью DataAdapter:

DataSet ds = new DataSet();
da.Fill(ds, "Goods");

Из приведенного выше примера видно, что метод Fill объекта da в качестве параметров использует имя объекта DataSet, куда необходимо поместить данные, возвращаемые в результате выполнения запроса, который определен в строке sqlString. Во втором параметре можно указать имя, которое будет сопоставлено с таблицей, созданной в DataSet. Из примера видно, что в данном случае не используется явный вызов метода Open объекта Connection - данный метод вызывается неявно при исполнении метода Fill. Таким образом, DataAdapter сперва открывает соединение с БД, затем выполняет необходимые манипуляции с данными, после чего закрывает открытое ранее соединение. Если по каким-то причинам такой алгоритм взаимодействия с базой данных требуется изменить, необходимо до вызова метода Fill открыть соединение с БД. В этом случае DataAdapter будет использовать уже существующее соединение.

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

Привязка и отображение данных

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

Большинство элементов управления ASP.NET поддерживают привязку данных. При этом привязка может работать как для данных с одним значением, так и для данных с множественными значениями. Привязка с одним значением означает, что элемент управления может отображать единственное значение, извлекаемое из источника данных. Такие принципы используются элементами управления TextBox, LinkButton, Image, Hyperlink. Привязка с множественными значениями означает, что элемент управления может отображать несколько значений, извлекаемых из источника данных. Элементы управления, поддерживающие привязку с множественными значениями, строятся на основе списков и электронных таблиц. Типичными представителями таких элементов управления являются ListBox и GridView.

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

Рассмотрим основные принципы использования обоих типов привязки данных.

Привязка с одним значением

Элементы управления, поддерживающие привязку данных с одним значением, позволяют осуществить привязку некоторых из их свойств к данным с помощью выражения привязки данных. Выражение привязки данных вводится в тексте страницы .aspx и заключается внутри ограничителей <%# %>.

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

Для того чтобы вычислить выражение привязки, необходимо в коде приложения вызвать метод Page.DataBind(). В момент вызова данного метода ASP.NET проверяет все выражения на текущей странице, при необходимости производит вычисления и заменяет их соответствующими значениями.

В качестве примера рассмотрим привязку элемента Label к данным таблицы "Товары". Для этого создадим метод GetProductName(), возвращающий в качестве значения содержимое первой строки столбца "НаименованиеТовара" таблицы "Товары".

public string GetProductName()
{
  return ds.Tables["Goods"].Rows[0]["НаименованиеТовара"].
   ToString();
}

Теперь необходимо добавить элемент Label на страницу .aspx и установить выражение привязки для свойства Text данного элемента.

<asp:Label ID="Label1" runat="server" Text="<%#GetProductName()
%>"></asp:Label>

В методе Page.Load() произведем вызов метода Page.DataBind().

Результат работы данного приложения представлен на рис. 10.11.

Результат отображения данных с использованием механизма привязки данных с одним значением

Рис. 10.11. Результат отображения данных с использованием механизма привязки данных с одним значением

Полный текст исходного кода данного примера выглядит следующим образом:

public partial class _Default : System.Web.UI.Page
{
  private DataSet ds;
  protected void Page_Load(object sender, EventArgs e)
  {
    string strCon = WebConfigurationManager.ConnectionStrings
     ["Test_Db"].ConnectionString;
    string sqlString = "SELECT КодТовара,НаименованиеТовара,Цена
     FROM Товары";
    SqlConnection sqlCon = new SqlConnection(strCon);

	SqlDataAdapter da = new SqlDataAdapter(sqlString,sqlCon);
    ds = new DataSet();
    da.Fill(ds, "Goods");
    this.DataBind();
  }

  public string GetProductName()
  {
    return ds.Tables["Goods"].Rows[0]["НаименованиеТовара"].
     ToString();
  }
}

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

Кроме выражений привязки, ASP.NET поддерживает также $-выражения, представляющие собой последовательность кода, которую можно добавлять на aspx-страницу и которая будет исполняться в момент обращения к странице. Visual Studio 2005 содержит встроенный построитель $-выражений, который позволяет извлекать пользовательские настройки приложения и информацию о строке подключения, расположенные в файле web.config. Например, для извлечения настройки приложения по имени MySetting и вывода ее содержимого на экран можно поместить на странице элемент Literal, в свойстве Text которого установить значение <%$ AppSettings:MySetting %>.

Такого же эффекта можно добиться, если использовать построитель выражений. Для этого необходимо в режиме редактирования дизайна открыть свойства объекта Literal и вызвать построитель выражений, нажав на кнопку( рис. 10.12). В открывшемся окне, изображенном на рис. 10.13, необходимо выбрать категорию AppSettings и в свойстве AppSetting установить значение MySetting. Теперь значение определенное в свойстве MySetting файла web.config, будет отображаться на странице.

Вызов построителя выражений

Рис. 10.12. Вызов построителя выражений
Окно построителя выражений

Рис. 10.13. Окно построителя выражений

Конечно, отображение значения свойства, определенного в файле web.config, имеет незначительное практическое значение. Однако извлечение таким образом строки подключения к базе данных, определенной в web.config, и запись ее значения в свойство ConnectionString объекта SqlDataSource, обеспечивающего подключение к базе данных, способно значительно облегчить задачу создания универсального механизма подключения к источнику данных. Использование элемента SqlDataSource будет рассмотрено ниже.

< Лекция 9 || Лекция 10: 12345678910