Доступ к данным с помощью элементов управления источником данных (DataSource) в ASP.NET 2.0

ОГЛАВЛЕНИЕ

Работа с данными в ASP.NET версии 1.x требует написания кода по осуществлению доступа к данным. Это подразумевает осуществление соединения к базе данных, указание SQL-команды и ее последующий запуск. Элементы управления источником данных в ASP.NET 2.0 значительно упрощают данный процесс путем инкапсуляции модели доступа к данным в пределах структуры элемента управления. Поэтому информация может быть получена либо изменена и затем привязана к элементу управления, и все это не требует написания кода.

В дополнение к возможности декларативного использования элементов управления источником данных, доступ к ним также может быть осуществлен программным путем. Вы можете добавить элемент управления SqlDataSource либо AccessDataSource на вашу веб-страницу, указать запрос типа SELECT, INSERT, UPDATE или DELETE, и затем программно выполнить одну из SQL-команд элемента. Такой подход пригоден в случаях, когда вам необходимо программно работать с данными, но в то же время обойтись без написания кода. Вкратце, использование элементов управления источником данных таким образом позволяет программно работать с данными, написав  лишь одну строку кода.

В данной статье мы рассмотрим способ использования элемента управления SqlDataSource для того, чтобы программно получать, вставлять и удалять информацию. Читайте далее, чтобы узнать больше об этом!

Программный запуск SQL-команд с элементами управления SqlDataSource и AccessDataSource

Элементы управления SqlDataSource и AccessDataSource могут быть использованы для того, чтобы осуществлять вставку, обновление, удаление и получение данных. SQL-команды, используемые для осуществления вставки, обновления, удаления и возврата данных, указаны посредством свойств InsertCommand, UpdateCommand, DeleteCommand и SelectCommand соответственно, и данные команды выполняются автоматически, когда элемент управления источником данных декларативно привязывается к элементу управления данными (такими, как GridView, DetailsView, DropDownList и т.д.).

SQL-команды, указанные в данных свойствах могут содержать параметры. К примеру, свойство SelectCommand может содержать запрос SELECT, который возвращает все товары определенной категории используя параметр под названием @CategoryID like so:

SELECT ProductID, ProductName, UnitPrice
FROM Products
WHERE Category = @CategoryID

Значение параметра может быть указано посредством элемента управления Parameter в наборе SelectParameters элемента управления источником данных. Элемент управления источником данных может использовать параметризированные запросы для всех своих SQL-команд (InsertCommand, UpdateCommand, DeleteCommand и SelectCommand), каждая из которых указана соответствующими свойствами наборов параметров (InsertParameters, UpdateParameters, DeleteParameters и SelectParameters соответственно ).

Элементы управления SqlDataSource и AccessDataSource предоставляют четыре метода, которые позволяют выполнение конкретной SQL-команды. Вот эти четыре метода:

  • Select(DataSourceSelectArguments) - выполняет SelectCommand и получает результаты либо в виде объекта DataView, либо как DataReader, в зависимости от значения свойства DataSourceMode элемента управления источником данных. Объект DataSourceSelectArguments , ожидаемый данным методом, используется для того, чтобы предоставить дополнительную информацию по тому, как информация должна быть обновлена до того, как будет возвращена. К примеру, при сортировке либо листании данных в GridView данный входной параметр используется для указания того, что данные отсортированы по определенной колонке либо то, что только определенное подмножество записей должно быть получено. В примерах данной статьи мы будем всегда передавать значение DataSourceSelectArguments.Empty, тем самым отображая то, что мы не хотим изменять данные.
  • Insert() - выполняет InsertCommand.
  • Update() - выполняет UpdateCommand.
  • Delete() - выполняет DeleteCommand.
Вкратце, данные могут быть получены, либо выражения INSERT, UPDATE или DELETE могут быть выполнены при помощи всего лишь одной строки кода. Стандартный код доступа к данным заключается в создании соединения к объекту (указав строку соединения, открытия соединения), в создании командного объекта (указав текст команды), и т.д. - это все обрабатывается элементом управления источником данных тогда, когда вызываются его методы Select(), Insert(), Update() или Delete().

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

Получаем результаты программным способом, используя элемент управления SqlDataSource

Для того чтобы программно получить результат из элемента управления источником данных, нам нужно сначала добавить элемент управления источником на страницу и указать его свойства. Чтобы продемонстрировать программную работу с данными, мы создадим страницу, которая позволит пользователю выбрать категорию товара из таблицы Categories. Кроме выбора категории, представьте, что мы хотим отобразить среднюю цену для товаров в данной категории, а также три самых дорогих товара (название и цену). Хотя мы можем выполнить все эти требования декларативно, используя такие элементы управления данными, как Repeater или FormView, мы все же будем использовать программный способ получения данной информации и отображения ее в элементе Label.

Следующий пример включает элемент DropDownList, названный Categories , который декларативно привязан к SqlDataSource, возвращающему  все категории. Страница также содержит два других элемента SqlDataSource, которые не привязаны ни к одному элементу управления. Первый, AvgPriceDataSource, возвращает среднее значение UnitPrice для указанной категории. Его SelectCommand было назначено следующему запросу:

SELECT AVG(UnitPrice) as AvgPrice
FROM Products
WHERE CategoryID = @CategoryID

Второй элемент управления, MostExpensiveProductsDataSource, возвращает значения ProductName и UnitPrice для трех самых дорогих товаров указанной категории, используя следующую SelectCommand команду:

SELECT TOP 3 ProductName, UnitPrice
FROM Products
WHERE CategoryID = @CategoryID
ORDER BY UnitPrice DESC

Оба элемента управления имеют единственный ControlParameter в их наборе SelectParameters, который заполняет значение параметра @CategoryID значением CategoryID , выбранного из элемента управления DropDownList, который назван Categories.

При программной работе с информацией, полученной из элемента управления SqlDataSource, стоит отметить свойство DataSourceMode. Свойство DataSourceMode указывает на тип объекта данных, возвращенного элементом SqlDataSource и оно может быть установлено в DataReader либо DataSet (по умолчанию). Если свойство DataSourceMode установлено в DataReader , то метод Select возвращает экземпляр объекта IDataReader; если оно установлено в DataSet , то возвращается объект DataView.

Разница немаловажна, поскольку код, который вы используете для программной работы с данными отличается между DataViews и Data Readers. Оба объекта могут работать со скалярными данными либо набором данных. Data Readers более эффективны при возврате данных, которые вам просто необходимо отобразить; DataViews предоставляет больше возможностей - возможность сортировать и фильтровать полученные данные, осуществлять беспорядочный доступ к записям, и т.д. AvgPriceDataSource SqlDataSource демонстрирует работу с Data Readers, в то время как MostExpensiveProductsDataSource показывает работу с DataViews.

Следующий метод вызывается в момент, когда изменяется индекс выборки элемента DropDownList и когда данные впервые привязывается к DropDownList. Как демонстрирует код, осуществляется программный вызов метода Select() элементов управления источником данных AvgPriceDataSource и MostExpensiveProductsDataSource и свойствам Text двух разных элементов Label назначается результирующая информация. Заметьте как синтаксис доступа к данным отличается в зависимости от того, что возвращает SqlDataSource - Data Reader или DataView.

Private Sub ProgrammaticallyBindToDataSourceControls()
   'Получаем среднюю цену DataReader
   Dim myReader As IDataReader = CType(AvgPriceDataSource.Select(DataSourceSelectArguments.Empty), IDataReader)
   If myReader.Read Then
      If Convert.IsDBNull(myReader("AvgPrice")) Then
         AvgPrice.Text = "Unknown"
      Else
         AvgPrice.Text = Convert.ToDecimal(myReader("AvgPrice")).ToString("c")
      End If
   End If


   'Получаем три самых дорогих товара в качестве DataView
   MostExpensiveProducts.Text = String.Empty
   Dim vwExpensiveItems As DataView = CType(MostExpensiveProductsDataSource.Select(DataSourceSelectArguments.Empty), DataView)

   'Проходим в цикле через каждую запись
   For Each rowProduct As DataRowView In vwExpensiveItems
      'В результате получаем название и цену
      MostExpensiveProducts.Text &= String.Format("{0} ({1:c}); ", rowProduct("ProductName"), rowProduct("UnitPrice"))
   Next
End Sub

Код, возвращающий данные из источника данных AvgPriceDataSource использует объект IDataReader. Он затем считывает данные используя метод Read. Поскольку UnitPrice может содержать пустые значения (NULL), может случиться и так, что все товары в выбранной категории имеют значение UnitPrice равное NULL, и в этом случае средняя цена также будет нулевой (NULL). Если такой случай будет реальностью, то мы отобразим "Unknown" (Неизвестно), в противном случае мы отобразим результат в формате валюты. Для того, чтобы получить три самых дорогих товара выбранной категории мы используем объект DataView и проходим в цикле по всех результирующим записям при помощи выражения For Each. Для каждой записи мы отобразим название и цену товара.


Вставка новой записи программным путем, используя элемент управления SqlDataSource

Элементы управления ASP.NET 2.0 предлагают возможности декларативной вставки, обновления и удаления данных. Не написав и строки кода, вы можете создать GridView, DetailsView или FormView, который отображает данные, а также позволяет пользователю редактировать, удалять и добавлять информацию. Тем не менее, бывают случаи, когда данный декларативный подход, не подразумевающий написания  кода, не будет тем, что вам необходимо. Конечно, всегда есть возможность написать самому код соединения к базе данных, написать выражение INSERT, UPDATE либо DELETE, и выполнить команду, но это все можно с легкостью сделать при помощи элементов управления источниками данных.

Представьте, что нам нужно создать интерфейс, позволяющий добавлять новые товары в таблицу Products. В частности, мы хотели бы иметь настраиваемый интерфейс, который, на данный момент, отображал бы текстовые поля для названий и цен на товары, DropDownList - для категории, и CheckBox - для состояния. Данный интерфейс также включал бы кнопку добавления ("Add Product"), при нажатии на которую будет добавлена новая запись в базу данных, используя значения, введенные пользователем.

Для того чтобы создать такую страницу без использования FormView либо какого-нибудь другого  из элементов управления данными, вам необходимо начать с добавления элементов TextBox, DropDownList, CheckBox и Button. Далее, добавьте элемент управления SqlDataSource, который указывает на следующее параметризированное выражение INSERT посредством его свойства InsertCommand:

INSERT INTO Products(ProductName, CategoryID, UnitPrice, Discontinued)
VALUES (@ProductName, @CategoryID, @UnitPrice, @Discontinued)

Установите соответствие между значениями параметров в наборе InsertParameters при помощи ControlParameters, которые указывают на соответствующие элементы управления страницы. Существует множество путей выполнения данного. Находясь в режиме дизайнера (Designer), нажмите на SqlDataSource и перейдите к окну свойств (Properties). Там вы увидите опцию InsertQuery, которая будучи отмеченной, отображает редактор команд и параметров (Command and Parameter Editor), как это продемонстрировано ниже. Здесь вы можете указать InsertCommand, параметры, и их источники. Заметьте, что каждый из четырех параметров использует элемент управления (Control) в качестве источника (Parameter source), при этом ControlID выпадающего списка установлен в соответствующий элемент управления на странице.


В качестве альтернативы данные параметры могут быть указаны посредством декларативного синтаксиса элемента управления SqlDataSource:

<asp:SqlDataSource ID="AddProductDataSource" runat="server" ConnectionString="..."
   InsertCommand="INSERT INTO Products(ProductName, CategoryID, UnitPrice, Discontinued) VALUES (@ProductName, @CategoryID, @UnitPrice, @Discontinued)"
   ProviderName="...">
   <InsertParameters>
      <asp:ControlParameter ControlID="ProductName" Name="ProductName" PropertyName="Text" />
      <asp:ControlParameter ControlID="Categories" Name="CategoryID" PropertyName="SelectedValue" />
      <asp:ControlParameter ControlID="UnitPrice" Name="UnitPrice" PropertyName="Text" />
      <asp:ControlParameter ControlID="Discontinued" Name="Discontinued" PropertyName="Checked" />
   </InsertParameters>
</asp:SqlDataSource>

В любом событии, как только элементы управления будут добавлены на страницу InsertCommand и InsertParameters элемента SqlDataSource будут правильно настроены, вставка новой записи будет  столь же проста, как вызов метода Insert() элемента управления источником данных. Единственным кодом, который вам придется написать, будет эта строка (которую мы расположили в обработчике события Click кнопки "Add Product" ):

Protected Sub btnAddProduct_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddProduct.Click
   'Добавляем новый товар
   AddProductDataSource.Insert()
End Sub