Поделиться через


Использование параметризованных запросов с помощью элемента управления SqlDataSource (VB)

Скотт Митчелл

Загрузить PDF-файл

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

Введение

В предыдущем руководстве мы узнали, как использовать элемент управления SqlDataSource для получения данных непосредственно из базы данных. С помощью мастера настройки источника данных можно выбрать базу данных, а затем выбрать столбцы, возвращаемые из таблицы или представления; введите пользовательскую инструкцию SQL; или используйте хранимую процедуру. Независимо от того, выбираете ли столбцы из таблицы или представления или вводите пользовательскую инструкцию SQL, свойству элемента управления SelectCommand SqlDataSource назначается результирующая нерегламентированная инструкция SQL SELECT , и именно эта SELECT инструкция выполняется при вызове метода SqlDataSource Select() (программно или автоматически из веб-элемента управления данных).

В инструкциях SQL SELECT , используемых в демонстрациях предыдущего руководства, отсутствуют WHERE предложения. SELECT В инструкции WHERE предложение можно использовать для ограничения возвращаемых результатов. Например, чтобы отобразить имена продуктов стоимостью более 50,00 долл. США, можно использовать следующий запрос:

SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00

Как правило, значения, используемые в WHERE предложении, определяются каким-либо внешним источником, например значением строки запроса, переменной сеанса или введенными пользователем данными из веб-элемента управления на странице. В идеале такие входные данные задаются с помощью параметров. В Microsoft SQL Server параметры обозначаются с помощью @parameterName, как в:

SELECT ProductName
FROM Products
WHERE UnitPrice > @Price

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

Примечание

В предыдущем руководстве мы сравнили ObjectDataSource, который был нашим инструментом выбора по сравнению с первыми 46 учебниками, с SqlDataSource, отметив их концептуальное сходство. Эти сходства также распространяются на параметры. Параметры ObjectDataSource, сопоставленные с входными параметрами для методов на уровне бизнес-логики. При использовании SqlDataSource параметры определяются непосредственно в SQL-запросе. Оба элемента управления имеют коллекции параметров для своих Select()методов , Insert(), Update()и Delete() , и оба могут иметь значения параметров, заполненные из предварительно определенных источников (значения строки запросов, переменные сеанса и т. д.) или назначаться программным способом.

Создание параметризованного запроса

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

  • Выбрав столбцы из существующей таблицы или представления,
  • Путем ввода пользовательской инструкции SQL или
  • Выбор хранимой процедуры

При выборе столбцов из существующей таблицы или представления параметры для WHERE предложения необходимо указать в диалоговом окне Добавление WHERE предложения. Однако при создании настраиваемой инструкции SQL можно ввести параметры непосредственно в WHERE предложение (с помощью @parameterName для обозначения каждого параметра). Хранимая процедура состоит из одной или нескольких инструкций SQL, и эти инструкции можно параметризовать. Однако параметры, используемые в инструкциях SQL, должны передаваться в качестве входных параметров хранимой процедуре.

Так как создание параметризованного запроса зависит от того, как заданы sqlDataSource SelectCommand , рассмотрим все три подхода. Чтобы начать работу, откройте страницу ParameterizedQueries.aspx в папкеSqlDataSource, перетащите элемент управления SqlDataSource из панели элементов на Designer и задайте для этого ID элемента значение Products25BucksAndUnderDataSource. Затем щелкните ссылку Настройка источника данных в смарт-теге элемента управления. Выберите базу данных для использования (NORTHWINDConnectionString) и нажмите кнопку Далее.

Шаг 1. Добавление предложения WHERE при выборе столбцов из таблицы или представления

При выборе данных, возвращаемых из базы данных с помощью элемента управления SqlDataSource, мастер настройки источника данных позволяет просто выбрать столбцы для возврата из существующей таблицы или представления (см. рис. 1). При этом автоматически создается инструкция SQL SELECT , которая отправляется в базу данных при вызове метода SqlDataSource Select() . Как и в предыдущем руководстве, выберите таблицу Products из раскрывающегося списка и проверка ProductIDстолбцы , ProductNameи UnitPrice .

Выбор столбцов для возврата из таблицы или представления

Рис. 1. Выбор столбцов, возвращаемых из таблицы или представления (щелкните для просмотра полноразмерного изображения)

Чтобы включить WHERE предложение в инструкцию SELECT , нажмите кнопку WHERE , которая открывает диалоговое окно Добавление WHERE предложения (см. рис. 2). Чтобы добавить параметр для ограничения результатов, возвращаемых запросом SELECT , сначала выберите столбец для фильтрации данных. Затем выберите оператор, используемый для фильтрации (=, <, <=, >и т. д.). Наконец, выберите источник значения параметра, например из строки запроса или состояния сеанса. После настройки параметра нажмите кнопку Добавить, чтобы включить его в SELECT запрос.

В этом примере давайте возвращаем только те результаты, где UnitPrice значение меньше или равно 25,00 долл. США. Поэтому выберите UnitPrice в раскрывающемся списке Столбец и <= в раскрывающемся списке Оператор. При использовании жестко закодированного значения параметра (например, 25,00 долл. США) или программном указании значения параметра выберите Нет в раскрывающемся списке Источник. Затем введите жестко закодированное значение параметра в текстовое поле Значение 25.00 и завершите процесс, нажав кнопку Добавить.

Ограничение результатов, возвращаемых из диалогового окна Добавление предложения WHERE

Рис. 2. Ограничение результатов, возвращаемых из диалогового окна Добавление WHERE предложения (щелкните для просмотра полноразмерного изображения)

После добавления параметра нажмите кнопку ОК, чтобы вернуться к мастеру настройки источника данных. Оператор SELECT в нижней части мастера теперь должен содержать WHERE предложение с параметром с именем @UnitPrice:

SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)

Примечание

Если в предложении указано несколько условий WHERE из диалогового окна Добавление WHERE предложения, мастер объединяет их с оператором AND . Если необходимо включить OR в WHERE предложение (например, WHERE UnitPrice <= @UnitPrice OR Discontinued = 1), необходимо создать инструкцию SELECT на пользовательском экране инструкции SQL.

Завершите настройку SqlDataSource (нажмите кнопку Далее, затем Готово), а затем проверьте декларативную разметку SqlDataSource. Теперь разметка включает коллекцию <SelectParameters> , в которой указаны источники параметров в SelectCommand.

<asp:SqlDataSource ID="Products25BucksAndUnderDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT [ProductID], [ProductName], [UnitPrice]
        FROM [Products] WHERE ([UnitPrice] <= @UnitPrice)">
    <SelectParameters>
        <asp:Parameter DefaultValue="25.00" Name="UnitPrice" Type="Decimal" />
    </SelectParameters>
</asp:SqlDataSource>

При вызове UnitPrice метода SqlDataSource Select() значение параметра (25.00) применяется к параметру @UnitPriceSelectCommand в перед отправкой в базу данных. В результате из Products таблицы возвращаются только те продукты, которые меньше или равны 25,00 долл. США. Чтобы подтвердить это, добавьте Элемент GridView на страницу, привяжите его к этому источнику данных, а затем просмотрите страницу в браузере. Вы должны увидеть только те продукты, которые меньше или равны 25,00 долл. США, как показано на рисунке 3.

Отображаются только те продукты, которые меньше или равны 25,00 долл. США

Рис. 3. Отображаются только те продукты, которые меньше или равно 25,00 долл. США (щелкните для просмотра полноразмерного изображения)

Шаг 2. Добавление параметров в настраиваемую инструкцию SQL

При добавлении настраиваемой инструкции SQL можно явно ввести WHERE предложение или указать значение в ячейке Фильтр построителя запросов. Чтобы продемонстрировать это, давайте отобразим только те продукты в GridView, цены которых меньше определенного порогового значения. Начните с добавления элемента TextBox на страницу ParameterizedQueries.aspx , чтобы получить это пороговое значение от пользователя. Присвойте свойству TextBox значение IDMaxPrice. Добавьте веб-элемент управления Button и задайте для его Text свойства значение Display Matching Products .

Затем перетащите Элемент GridView на страницу и из его смарт-тега выберите для создания sqlDataSource с именем ProductsFilteredByPriceDataSource. В мастере настройки источника данных перейдите к экрану Укажите пользовательскую инструкцию SQL или хранимую процедуру (см. рис. 4) и введите следующий запрос:

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0

После ввода запроса (вручную или с помощью построителя запросов) нажмите кнопку Далее.

Возвращает только те продукты, которые меньше или равно значению параметра

Рис. 4. Возврат только тех продуктов, которые меньше или равно значению параметра (щелкните для просмотра полноразмерного изображения)

Так как запрос содержит параметры, на следующем экране мастера появится запрос на ввод источника значений параметров. Выберите Элемент Управления в раскрывающемся списке Источник параметров и MaxPrice (значение элемента управления ID TextBox) в раскрывающемся списке ControlID. Вы также можете ввести необязательное значение по умолчанию, которое будет использоваться в случае, если пользователь не ввел текст в MaxPrice элемент TextBox. Пока не вводите значение по умолчанию.

Текстовое свойство MaxPrice TextBox используется в качестве источника параметров

Рис. 5. Свойство MaxPrice TextBox Text используется в качестве источника параметров (щелкните для просмотра полноразмерного изображения)

Завершите работу мастера настройки источника данных, нажав кнопку Далее, а затем — Готово. Декларативная разметка для GridView, TextBox, Button и SqlDataSource:

Maximum price:
$<asp:TextBox ID="MaxPrice" runat="server" Columns="5" />
 
<asp:Button ID="DisplayProductsLessThanButton" runat="server"
    Text="Display Matching Products" />
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
    DataSourceID="ProductsFilteredByPriceDataSource" EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            HtmlEncode="False" DataFormatString="{0:c}"
            SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsFilteredByPriceDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT ProductName, UnitPrice 
        FROM Products WHERE UnitPrice <= @MaximumPrice">
    <SelectParameters>
        <asp:ControlParameter ControlID="MaxPrice" Name="MaximumPrice"
            PropertyName="Text" />
    </SelectParameters>
</asp:SqlDataSource>

Обратите внимание, что параметром в разделе SqlDataSource <SelectParameters> является ControlParameter, который включает дополнительные свойства, такие как ControlID и PropertyName. При вызове ControlParameter метода SqlDataSource Select() объект получает значение из указанного свойства веб-элемента управления и назначает его соответствующему параметру SelectCommandв . В этом примере MaxPrice в качестве @MaxPrice значения параметра используется свойство Text .

Просмотрите эту страницу в браузере. При первом посещении страницы или при отсутствии MaxPrice значения элемента TextBox в GridView записи не отображаются.

При пустом поле MaxPrice TextBox не отображается записей

Рис. 6. При пустом MaxPrice поле TextBox не отображается записей (щелкните для просмотра полноразмерного изображения)

Причина, по которой продукты не отображаются, заключается в том, что по умолчанию пустая строка для значения параметра преобразуется в значение базы данных NULL . Так как сравнение [UnitPrice] <= NULL всегда принимает значение False, результаты не возвращаются.

Введите в текстовое поле значение, например 5.00, и нажмите кнопку Показать соответствующие продукты. При обратной отправке SqlDataSource сообщает GridView о том, что один из источников параметров изменился. Следовательно, GridView повторно привязывается к SqlDataSource, отображая эти продукты меньше или равно 5,00 долл. США.

Отображаются продукты, не превышающие 5,00 долл. США

Рис. 7. Отображаются продукты, не превышающие 5,00 долл. США (щелкните для просмотра полноразмерного изображения)

Первоначальное отображение всех продуктов

Вместо отображения продуктов при первой загрузке страницы может потребоваться отобразить все продукты. Один из способов перечисления всех продуктов, когда MaxPrice TextBox пуст, — задать для параметра значение по умолчанию, например 10000000, так как маловероятно, что Northwind Traders когда-либо будет иметь запасы, цена за единицу которых превышает $1,000,000. Однако этот подход является недальновидным и может не работать в других ситуациях.

В предыдущих руководствах по декларативным параметрам и фильтрации основных и подробных данных с помощью DropDownList мы столкнулись с аналогичной проблемой. Наше решение — поместить эту логику на уровень бизнес-логики. В частности, BLL изучил входящее значение и, если это было NULL или какое-то зарезервированное значение, вызов был перенаправлен в метод DAL, который вернул все записи. Если входящее значение было обычным значением фильтрации, был выполнен вызов метода DAL, выполняющего инструкцию SQL, которая использовала параметризованное WHERE предложение с предоставленным значением.

К сожалению, мы обходим архитектуру при использовании SqlDataSource. Вместо этого необходимо настроить инструкцию SQL для интеллектуального захвата всех записей, если @MaximumPrice параметр имеет NULL или какое-либо зарезервированное значение. В этом упражнении давайте создадим его, чтобы, если @MaximumPrice параметр равен -1.0, то должны быть возвращены все записи (-1.0 работает как зарезервированное значение, так как ни в каких продуктах не может быть отрицательных UnitPrice значений). Для этого можно использовать следующую инструкцию SQL:

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0

Это WHERE предложение возвращает все записи, @MaximumPrice если параметр равен -1.0. Если значение параметра не -1.0равно , возвращаются только те продукты, значение которых UnitPrice меньше или равно значению @MaximumPrice параметра. Если задать для параметра значение @MaximumPrice по умолчанию , при первой загрузке страницы (или при каждом MaxPrice пустом поле TextBox), @MaximumPrice будет иметь значение -1.0 , и будут отображаться все -1.0продукты.

Теперь отображаются все продукты при пустом поле MaxPrice TextBox

Рис. 8. Теперь отображаются все продукты при пустом текстовом MaxPrice поле (щелкните для просмотра полноразмерного изображения)

Существует несколько предостережений, которые следует отметить при этом подходе. Во-первых, учтите, что тип данных параметра определяется его использованием в SQL-запросе. Если изменить WHERE предложение с @MaximumPrice = -1.0 на @MaximumPrice = -1, среда выполнения будет рассматривать параметр как целое число. Если затем попытаться присвоить MaxPrice элементу TextBox десятичное значение (например, 5,00), возникнет ошибка, так как не удается преобразовать значение 5,00 в целое число. Чтобы устранить эту проблему, убедитесь, что вы используете @MaximumPrice = -1.0 в предложении WHERE , или, что еще лучше, задайте ControlParameter для свойства объекта Type значение Decimal .

Во-вторых, добавив OR @MaximumPrice = -1.0 в WHERE предложение , обработчик запросов не может использовать индекс для UnitPrice (при условии, что он существует), что приводит к сканированию таблицы. Это может повлиять на производительность, если в таблице имеется достаточно большое количество записей Products . Лучший подход состоит в том, чтобы переместить эту логику в хранимую процедуру, в IF которой оператор будет либо выполнять SELECT запрос из Products таблицы без предложения, WHERE когда необходимо вернуть все записи, либо оператор, предложение которого WHERE содержит только UnitPrice критерии, чтобы можно было использовать индекс.

Шаг 3. Создание и использование параметризованных хранимых процедур

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

Чтобы проиллюстрировать использование хранимых процедур в SqlDataSource, создайте в базе данных Northwind новую хранимую процедуру с именем GetProductsByCategory, которая принимает параметр с именем @CategoryID и возвращает все столбцы продуктов, столбец которых CategoryID соответствует @CategoryID. Чтобы создать хранимую процедуру, перейдите к Обозреватель сервера и изучите NORTHWND.MDF базу данных. (Если Обозреватель сервера не отображается, откройте его, перейдя в меню Вид и выбрав параметр Сервер Обозреватель.)

В базе данных щелкните правой NORTHWND.MDF кнопкой мыши папку Хранимые процедуры, выберите Добавить новую хранимую процедуру и введите следующий синтаксис:

CREATE PROCEDURE dbo.GetProductsByCategory
(
      @CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID

Щелкните значок Сохранить (или CTRL+S), чтобы сохранить хранимую процедуру. Вы можете проверить хранимую процедуру, щелкнув ее правой кнопкой мыши в папке Хранимые процедуры и выбрав команду Выполнить. Появится запрос на ввод параметров хранимой процедуры (@CategoryIDв данном экземпляре), после чего результаты будут отображаться в окне Вывод.

Хранимая процедура GetProductsByCategory при выполнении с <span class=@CategoryID 1" />

Рис. 9. Хранимая GetProductsByCategory процедура при выполнении с значением @CategoryID 1 (щелкните для просмотра полноразмерного изображения)

Позвольте использовать эту хранимую процедуру для отображения всех продуктов в категории «Напитки» в GridView. Добавьте новый элемент GridView на страницу и привяжите его к новому объекту SqlDataSource с именем BeverageProductsDataSource. Перейдите на экран Укажите пользовательскую инструкцию SQL или хранимую процедуру, установите переключатель Хранимая процедура и выберите GetProductsByCategory хранимую процедуру из раскрывающегося списка.

Выберите хранимую процедуру GetProductsByCategory из списка Drop-Down

Рис. 10. Выберите хранимую GetProductsByCategory процедуру из списка Drop-Down (щелкните для просмотра полноразмерного изображения)

Так как хранимая процедура принимает входной параметр (@CategoryID), при нажатии кнопки Далее предлагается указать источник для значения этого параметра. Напитки CategoryID равны 1, поэтому оставьте раскрывающийся список Источник параметров в поле Нет и введите 1 в текстовое поле DefaultValue.

Используйте значение Hard-Coded 1 для возврата продуктов в категории

Рис. 11. Используйте значение Hard-Coded 1 для возврата продуктов в категории "Напитки" (щелкните, чтобы просмотреть полноразмерное изображение)

Как показано в следующей декларативной разметке, при использовании хранимой процедуры свойству SqlDataSource SelectCommand присваивается имя хранимой процедуры, а SelectCommandType свойству присваивается StoredProcedureзначение , указывающее, что SelectCommand является именем хранимой процедуры, а не специальной инструкцией SQL.

<asp:SqlDataSource ID="BeverageProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" />
    </SelectParameters>
</asp:SqlDataSource>

Протестируйте страницу в браузере. Отображаются только те продукты, которые относятся к категории Напитки, хотя отображаются все поля продукта, так как хранимая GetProductsByCategory процедура возвращает все столбцы из Products таблицы. Конечно, можно ограничить или настроить поля, отображаемые в GridView в диалоговом окне Изменение столбцов GridView.

Отображаются все напитки

Рис. 12. Отображаются все напитки (щелкните, чтобы просмотреть полноразмерное изображение)

Шаг 4. Программный вызов оператора Select() SqlDataSource

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

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

Для этого нам нужны два элемента управления SqlDataSource, один для получения случайной категории из Categories таблицы, а другой — для получения продуктов категории. Мы создадим sqlDataSource, который получает случайную запись категории на этом шаге; На шаге 5 рассматривается создание sqlDataSource, который извлекает продукты категории.

Начните с добавления SqlDataSource ParameterizedQueries.aspx в и задайте для него ID значение RandomCategoryDataSource. Настройте его таким образом, чтобы он использовал следующий SQL-запрос:

SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()

ORDER BY NEWID() возвращает записи, отсортированные в случайном порядке (см . раздел Использование NEWID() для случайной сортировки записей). SELECT TOP 1 возвращает первую запись из результирующих наборов. В совокупности этот запрос возвращает значения столбцов CategoryID и CategoryName из одной случайно выбранной категории.

Чтобы отобразить значение категории CategoryName , добавьте на страницу элемент управления Label Web, задайте для его ID свойства CategoryNameLabelзначение и очистите его Text свойство. Чтобы программным способом получить данные из элемента управления SqlDataSource, необходимо вызвать его Select() метод . МетодSelect() ожидает один входной параметр типа DataSourceSelectArguments, который указывает способ отправки данных перед возвратом. Сюда могут входить инструкции по сортировке и фильтрации данных. Он используется веб-элементами управления данными при сортировке или разбиении по страницам данных из элемента управления SqlDataSource. В нашем примере, однако, нам не нужно изменять данные перед возвратом, и поэтому мы будем передавать объект DataSourceSelectArguments.Empty .

Метод Select() возвращает объект , реализующий IEnumerable. Точный возвращаемый тип зависит от значения свойства элемента управления DataSourceModeSqlDataSource. Как обсуждалось в предыдущем руководстве, этому свойству можно присвоить значение DataSet или DataReader. Если задано значение DataSet, Select() метод возвращает объект DataView ; если задано значение DataReader, он возвращает объект , реализующий IDataReader. RandomCategoryDataSource Так как свойство SqlDataSource имеет DataSourceMode значение DataSet (по умолчанию), мы будем работать с объектом DataView.

В следующем коде показано, как получить записи из RandomCategoryDataSource SqlDataSource в виде DataView, а также как считывать CategoryName значение столбца из первой строки DataView:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles Me.Load
    ' Get the data from the SqlDataSource as a DataView
    Dim randomCategoryView As DataView = CType _
        (RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty), DataView)
    If randomCategoryView.Count > 0 Then
        ' Assign the CategoryName value to the Label
        CategoryNameLabel.Text = String.Format( _
            "Here are Products in the {0} Category...", _
            randomCategoryView(0)("CategoryName").ToString())
    End If
End Sub

randomCategoryView(0) возвращает первый DataRowView объект в DataView. randomCategoryView(0)("CategoryName") возвращает значение столбца CategoryName в этой первой строке. Обратите внимание, что DataView имеет слабое типизированное представление. Чтобы сослаться на определенное значение столбца, необходимо передать имя столбца в виде строки (в данном случае CategoryName). На рисунке 13 показано сообщение, отображаемое в при CategoryNameLabel просмотре страницы. Конечно, отображаемое имя категории выбирается sqlDataSource случайным RandomCategoryDataSource образом при каждом посещении страницы (включая обратные передачи).

Отображается имя случайно выбранной категории

Рис. 13. Отображается имя случайно выбранной категории (щелкните для просмотра полноразмерного изображения)

Примечание

Если свойству элемента управления DataSourceMode SqlDataSource присвоено значение DataReader, возвращаемое из метода значение Select() должно быть приведено к IDataReader. Чтобы прочитать значение столбца CategoryName из первой строки, используйте следующий код:

If randomCategoryReader.Read() Then
   Dim categoryName as String = randomCategoryReader("CategoryName').ToString()
   ...
End If

Когда SqlDataSource случайным образом выбирает категорию, мы готовы добавить GridView, который перечисляет продукты категории.

Примечание

Вместо того, чтобы использовать веб-элемент управления Label для отображения имени категории, мы могли бы добавить FormView или DetailsView на страницу, привязав их к SqlDataSource. Однако использование Label позволило изучить, как программно вызывать инструкцию SqlDataSource Select() и работать с результирующей данными в коде.

Шаг 5. Назначение значений параметров программным способом

Во всех примерах, которые мы видели в этом руководстве, использовалось либо жестко закодированное значение параметра, либо значение, взятое из одного из предварительно определенных источников параметров (значение строки запроса, веб-элемент управления на странице и т. д.). Однако параметры элемента управления SqlDataSource также можно задать программным способом. Для завершения текущего примера нам нужен SqlDataSource, который возвращает все продукты, относящиеся к указанной категории. Этот sqlDataSource будет иметь CategoryID параметр, значение которого необходимо задать на CategoryID основе значения столбца, возвращаемого RandomCategoryDataSource SqlDataSource в обработчике Page_Load событий.

Сначала добавьте GridView на страницу и привяжите его к новому объекту SqlDataSource с именем ProductsByCategoryDataSource. Как и на шаге 3, настройте SqlDataSource таким образом, чтобы он вызвал хранимую GetProductsByCategory процедуру. Оставьте для раскрывающегося списка Источник параметров значение Нет, но не вводите значение по умолчанию, так как мы задаем это значение по умолчанию программным способом.

Снимок экрана: окно

Рис. 14. Не указывать источник параметров или значение по умолчанию (щелкните для просмотра полноразмерного изображения)

После завершения работы мастера SqlDataSource итоговая декларативная разметка должна выглядеть примерно так:

<asp:SqlDataSource ID="ProductsByCategoryDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter Name="CategoryID" Type="Int32" />
    </SelectParameters>
</asp:SqlDataSource>

Можно назначить DefaultValueCategoryID параметр программно в обработчике Page_Load событий:

' Assign the ProductsByCategoryDataSource's
' CategoryID parameter's DefaultValue property
ProductsByCategoryDataSource.SelectParameters("CategoryID").DefaultValue = _
    randomCategoryView(0)("CategoryID").ToString()

С этим дополнением страница содержит Элемент GridView, в который отображаются продукты, связанные со случайно выбранной категорией.

Снимок экрана: страница

Рис. 15. Не указывать источник параметров или значение по умолчанию (щелкните для просмотра полноразмерного изображения)

Сводка

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

Как и в случае с ObjectDataSource, SqlDataSource также предоставляет возможности для изменения базовых данных. В следующем руководстве мы рассмотрим, как определить INSERTоператоры , UPDATEи DELETE с помощью SqlDataSource. После добавления этих инструкций можно использовать встроенные функции вставки, редактирования и удаления, присущие элементам управления GridView, DetailsView и FormView.

Счастливое программирование!

Об авторе

Скотт Митчелл (Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с Веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часа. Его можно связать по адресу mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.

Отдельная благодарность

Эта серия учебников была проверена многими полезными рецензентами. В этом руководстве были ведущие рецензенты Скотт Клайд, Рэнделл Шмидт и Кен Песписа. Хотите ознакомиться с моими предстоящими статьями MSDN? Если да, опустите мне строку в mitchell@4GuysFromRolla.com.