通过 SqlDataSource 使用参数化查询 (VB)

作者 :Scott Mitchell

下载 PDF

在本教程中,我们继续了解 SqlDataSource 控件,并了解如何定义参数化查询。 参数可以通过声明方式和编程方式指定,并且可以从多个位置(如 querystring、会话状态、其他控件等)拉取。

简介

在上一教程中,我们了解了如何使用 SqlDataSource 控件直接从数据库中检索数据。 使用“配置数据源”向导,我们可以选择数据库,然后选取要从表或视图返回的列;输入自定义 SQL 语句;或使用存储过程。 无论是从表或视图中选择列,还是输入自定义 SQL 语句,都会为 SqlDataSource 控件的 SelectCommand 属性分配生成的即席 SQL SELECT 语句,并且当以编程方式或自动从数据 Web 控件) (调用 SqlDataSource 方法Select()时,将执行此SELECT语句。

上一教程演示中使用的 SQL SELECT 语句缺少 WHERE 子句。 在 语句中SELECTWHERE, 子句可用于限制返回的结果。 例如,若要显示成本超过 50.00 美元的产品名称,可以使用以下查询:

SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00

通常,子句中使用的 WHERE 值由某些外部源确定,例如查询字符串值、会话变量或页面上 Web 控件的用户输入。 理想情况下,此类输入是通过使用 参数指定的。 使用 Microsoft SQL Server时,参数使用 @parameterName表示,如下所示:

SELECT ProductName
FROM Products
WHERE UnitPrice > @Price

SqlDataSource 支持参数化查询,适用于 SELECT 语句和 INSERTUPDATEDELETE 语句。 此外,参数值可以从各种源自动拉取查询字符串、会话状态、页面上的控件等,也可以以编程方式分配。 本教程介绍如何定义参数化查询,以及如何以声明方式和编程方式指定参数值。

注意

在上一教程中,我们比较了 ObjectDataSource,它是我们选择的工具,而不是前 46 个教程与 SqlDataSource,并指出它们的概念相似性。 这些相似性还扩展到参数。 映射到业务逻辑层中方法的输入参数的 ObjectDataSource 参数。 使用 SqlDataSource 时,参数直接在 SQL 查询中定义。 这两个控件都有其 Select()Insert()Update()Delete() 方法的参数集合,并且两者都可以从预定义的源填充这些参数值, (查询字符串值、会话变量等) 或以编程方式分配。

创建参数化查询

SqlDataSource 控件的“配置数据源”向导提供了三种用于定义要执行的命令以检索数据库记录的方法:

  • 从现有表或视图中选取列,
  • 通过输入自定义 SQL 语句,或
  • 通过选择存储过程

从现有表或视图中选取列时,必须通过“添加WHERE子句”对话框指定 子句的参数WHERE。 但是,创建自定义 SQL 语句时,可以将参数直接输入到 WHERE 子句中, (使用 @parameterName 来表示每个参数) 。 存储过程由一个或多个 SQL 语句组成,这些语句可以参数化。 但是,SQL 语句中使用的参数必须作为输入参数传入存储过程。

由于创建参数化查询取决于 SqlDataSource 的 SelectCommand 指定方式,因此我们来看看这三种方法。 若要开始,请打开 文件夹中的页面ParameterizedQueries.aspx,将 SqlDataSource 控件从“工具箱”拖动到Designer,并将其设置为 IDProducts25BucksAndUnderDataSourceSqlDataSource 接下来,单击控件智能标记中的“配置数据源”链接。 选择要使用 (NORTHWINDConnectionString) 的数据库,然后单击“下一步”。

步骤 1:从表或视图中选取列时添加 WHERE 子句

使用 SqlDataSource 控件选择要从数据库返回的数据时,“配置数据源”向导允许我们仅选择要从现有表或视图返回的列 (请参阅图 1) 。 这样做会自动生成 SQL SELECT 语句,该语句是在调用 SqlDataSource 方法 Select() 时发送到数据库的内容。 正如我们在上一教程中所做的那样,从下拉列表中选择“产品”表,检查 ProductIDProductNameUnitPrice 列。

选择要从表或视图返回的列

图 1:选择要从表或视图返回的列 (单击以查看全尺寸图像)

WHERE若要在 SELECT 语句中包含 子句,请单击 WHERE 按钮,这将打开 “添加WHERE子句” 对话框 (请参阅图 2) 。 若要添加参数以限制查询返回 SELECT 的结果,请首先选择要按其筛选数据的列。 接下来,选择要用于筛选) (=、 <、 <、 >、、 等的运算符。 最后,从查询字符串或会话状态中选择参数值的源,例如 。 配置参数后,单击“添加”按钮将其包含在查询中 SELECT

在此示例中,让我们仅返回值小于或等于 $25.00 的那些结果 UnitPrice 。 因此,请从“列”下拉列表中选取 ,<从“运算符”下拉列表中选取 UnitPrice = 。 使用硬编码参数值 ((如 $25.00) )时,或者如果要以编程方式指定参数值,请从“源”下拉列表中选择“无”。 接下来,在“值”文本框中输入硬编码的参数值 25.00,然后单击“添加”按钮完成该过程。

限制从“添加 WHERE 子句”对话框返回的结果

图 2:限制从“添加 WHERE 子句”对话框返回的结果 (单击以查看全尺寸图像)

添加 参数后,单击“确定”返回到“配置数据源”向导。 SELECT向导底部的 语句现在应包含一个WHERE子句,其中包含名为 的参数@UnitPrice

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

注意

如果在 “添加WHERE子句” 对话框中的 WHERE 子句中指定了多个条件,向导会将它们与 AND 运算符联接。 如果需要在 WHERE 子句 ((如 WHERE UnitPrice <= @UnitPrice OR Discontinued = 1) )中包含 OR ,则必须通过自定义 SQL 语句屏幕生成SELECT语句。

完成 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>

调用 SqlDataSource 方法Select()时,UnitPrice (25.00) 的参数值将应用于 中的 SelectCommand 参数,@UnitPrice然后再发送到数据库。 最终结果是,仅从 Products 表中返回小于或等于 $25.00 的产品。 若要确认这一点,请将 GridView 添加到页面,将其绑定到此数据源,然后通过浏览器查看页面。 只应看到列出的那些低于或等于 $25.00 的产品,如图 3 所示。

仅显示小于或等于 $25.00 的产品

图 3:仅显示小于或等于 $25.00 的产品 (单击以查看全尺寸图像)

步骤 2:向自定义 SQL 语句添加参数

添加自定义 SQL 语句时,可以显式输入 子句或在 WHERE 查询生成器的 Filter 单元格中指定值。 为了演示这一点,让我们在 GridView 中仅显示价格低于特定阈值的产品。 首先,将 TextBox 添加到页面, ParameterizedQueries.aspx 以便从用户那里收集此阈值。 将 TextBox 属性 ID 设置为 MaxPrice。 添加按钮 Web 控件,并将其 Text 属性设置为显示匹配产品 。

接下来,将 GridView 拖到页面上,并从其智能标记中选择创建名为 ProductsFilteredByPriceDataSource的新 SqlDataSource。 在“配置数据源”向导中,转到“指定自定义 SQL 语句或存储过程”屏幕 (请参阅图 4) 并输入以下查询:

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

手动或通过查询生成器) 输入查询 (后,单击“下一步”。

仅返回小于或等于参数值的那些产品

图 4:仅返回小于或等于参数值的那些产品 (单击以查看全尺寸图像)

由于查询包含参数,向导中的下一个屏幕将提示我们输入参数值的源。 从“参数源”下拉列表中选择“控件”,然后 MaxPrice (“ControlID”下拉列表) TextBox 控件 ID 的值。 还可以输入可选的默认值,以在用户未在 TextBox 中 MaxPrice 输入任何文本的情况下使用。 暂时不要输入默认值。

MaxPrice TextBox 的 Text 属性用作参数源

图 5:TextBox MaxPrice 属性 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其中包括 和 PropertyName等其他ControlID属性。 调用 SqlDataSource 方法 Select() 时, ControlParameter 从指定的 Web 控件属性中获取值并将其分配给 中的 SelectCommand相应参数。 在此示例中, MaxPrice Text 属性用作 @MaxPrice 参数值。

花一点时间通过浏览器查看此页面。 首次访问页面时或每当 MaxPrice TextBox 缺少值时,GridView 中不会显示任何记录。

MaxPrice TextBox 为空时不显示任何记录

图 6:TextBox 为空时 MaxPrice 不显示任何记录 (单击以查看全尺寸图像)

不显示任何产品的原因是,默认情况下,参数值的空字符串将转换为数据库 NULL 值。 由于 的 [UnitPrice] <= NULL 比较始终为 False,因此不会返回任何结果。

在文本框中输入一个值(如 5.00),然后单击“显示匹配产品”按钮。 回发时,SqlDataSource 会通知 GridView 其参数源之一已更改。 因此,GridView 会重新绑定到 SqlDataSource,显示小于或等于 $5.00 的产品。

显示小于或等于 $5.00 的产品

图 7:显示小于或等于 $5.00 的产品 (单击以查看全尺寸图像)

最初显示所有产品

我们可能希望显示所有产品,而不是在首次加载页面时不显示 任何 产品。 每当 MaxPrice TextBox 为空时列出所有产品的一种方法是将参数默认值设置为一些疯狂的高值,如 1000000,因为 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

如果 @MaximumPrice 参数等于 -1.0,则此WHERE子句返回所有记录。 如果参数值不-1.0为 ,则仅返回小于或等于@MaximumPrice参数值的产品UnitPrice。 通过将 参数的 @MaximumPrice 默认值设置为 -1.0,在第一页上加载 (或每当 MaxPrice TextBox) 为空时, @MaximumPrice 都会有一个 值 -1.0 ,并且将显示所有产品。

现在,当 MaxPrice 文本框为空时,将显示所有产品

图 8:现在,TextBox 为空时 MaxPrice 显示所有产品 (单击以查看全尺寸图像)

此方法需要注意几个注意事项。 首先,请注意参数 的数据类型是由它在 SQL 查询中的用法推断的。 如果将 子句从 @MaximumPrice = -1.0 更改为 WHERE@MaximumPrice = -1,运行时会将 参数视为整数。 如果随后尝试将 MaxPrice TextBox 分配给十进制值 ((如 5.00 ) ),则会发生错误,因为它无法将 5.00 转换为整数。 若要解决此问题,请确保在 子句中使用@MaximumPrice = -1.0WHERE,或者最好将 ControlParameter object s Type 属性设置为 Decimal 。

其次,通过将 添加到 OR @MaximumPrice = -1.0WHERE 子句,查询引擎不能在 UnitPrice (上使用索引(假设) 存在索引),从而导致表扫描。 如果表中有足够多的记录 Products ,这可能会影响性能。 更好的方法是将此逻辑移动到存储过程,在该IF存储过程中,语句会在需要返回所有记录时从Products表中执行SELECT查询,而无需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 存储过程

图 9GetProductsByCategory 使用 @CategoryID 1 (单击查看全尺寸图像)

让我们使用此存储过程在 GridView 中显示饮料类别中的所有产品。 将新的 GridView 添加到页面,并将其绑定到名为 BeverageProductsDataSource的新 SqlDataSource。 继续“指定自定义 SQL 语句或存储过程”屏幕,选择“存储过程”单选按钮,然后从下拉列表中选择 GetProductsByCategory 存储过程。

从 Drop-Down 列表中选择 GetProductsByCategory 存储过程

图 10GetProductsByCategory 从 Drop-Down 列表中选择存储过程 (单击以查看全尺寸图像)

由于存储过程接受输入参数 (@CategoryID) ,因此单击“下一步”将提示指定此参数值的来源。 “饮料 CategoryID ”为 1,因此将“参数源”下拉列表保留为“无”,并在“DefaultValue”文本框中输入 1。

使用 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:以编程方式调用 SqlDataSource 的 Select () 语句

我们在上一教程和本教程中看到的示例已将 SqlDataSource 控件直接绑定到 GridView。 但是,可以通过编程方式访问 SqlDataSource 控件的数据,并在代码中枚举。 如果需要查询数据来检查数据,但不需要显示数据,这尤其有用。 你可以让 SqlDataSource 处理此单调代码,而不必编写所有样板 ADO.NET 代码来连接到数据库、指定命令并检索结果。

为了说明如何以编程方式处理 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 从结果集中返回第一条记录。 总之,此查询从单个随机选择的类别中返回 CategoryIDCategoryName 列值。

若要显示类别值 CategoryName ,请向页面添加标签 Web 控件,将其 ID 属性设置为 CategoryNameLabel,然后清除其 Text 属性。 若要以编程方式从 SqlDataSource 控件检索数据,需要调用其 Select() 方法。 方法Select()需要类型的DataSourceSelectArguments单个输入参数,该参数指定在返回数据之前应如何发送消息。 这可以包括有关对数据进行排序和筛选的说明,数据 Web 控件在对 SqlDataSource 控件中的数据进行排序或分页时使用。 不过,对于我们的示例,在返回数据之前不需要修改数据,因此将传入 DataSourceSelectArguments.Empty 对象。

方法 Select() 返回实现 的对象 IEnumerable。 返回的精确类型取决于 SqlDataSource 控件 属性DataSourceMode的值。 如上一教程中所述,可以将此属性设置为 或 DataReader的值DataSet。 如果 设置为 DataSet,则 Select() 方法返回 DataView 对象;如果设置为 DataReader,则返回实现 的对象 IDataReaderRandomCategoryDataSource由于 SqlDataSource 的DataSourceMode属性设置为 DataSet (默认) ,因此我们将处理 DataView 对象。

以下代码演示如何以 DataView 的形式从 RandomCategoryDataSource SqlDataSource 检索记录,以及如何从第一个 DataView 行中读取 CategoryName 列值:

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) 返回 DataView 中的第一个 DataRowViewrandomCategoryView(0)("CategoryName") 返回第一行中列的值 CategoryName 。 请注意,DataView 是松散类型。 若要引用特定的列值,需要将列的名称作为 CategoryName ( 字符串传递,在本例中) 。 图 13 显示了查看页面时在 中显示的 CategoryNameLabel 消息。 当然,每次访问页面时,SqlDataSource 都会随机选择 RandomCategoryDataSource 显示的实际类别名称 (包括回发) 。

显示随机选择的类别名称

图 13:显示随机选择的类别名称 (单击以查看全尺寸图像)

注意

如果 SqlDataSource 控件 的 DataSourceMode 属性已设置为 DataReader,则方法的 Select() 返回值需要强制转换为 IDataReader。 若要从第一行读取 CategoryName 列值,请使用如下代码:

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

随着 SqlDataSource 随机选择类别,我们准备添加列出类别产品的 GridView。

注意

我们可以将 FormView 或 DetailsView 添加到页面,并将其绑定到 SqlDataSource,而不是使用 Label Web 控件来显示类别的名称。 但是,通过使用 Label,我们可以探索如何以编程方式调用 SqlDataSource s Select() 语句并在代码中处理其生成的数据。

步骤 5:以编程方式分配参数值

到目前为止,我们在本教程中看到的所有示例都使用了硬编码参数值或从某个预定义参数源获取的参数值, (查询字符串值、页面上的 Web 控件等) 。 但是,也可以以编程方式设置 SqlDataSource 控件的参数。 若要完成当前示例,我们需要一个 SqlDataSource,用于返回属于指定类别的所有产品。 此 SqlDataSource 将具有一个CategoryID参数,需要根据CategoryID事件处理程序中 Page_Load SqlDataSource 返回的RandomCategoryDataSource列值设置其值。

首先,将 GridView 添加到页面,并将其绑定到名为 ProductsByCategoryDataSource的新 SqlDataSource。 就像我们在步骤 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 查询和存储过程创建参数化查询。 我们还介绍了如何使用硬编码参数源、将 Web 控件用作参数源,以及以编程方式指定参数值。

与 ObjectDataSource 一样,SqlDataSource 还提供修改其基础数据的功能。 在下一教程中,我们将了解如何使用 SqlDataSource 定义 INSERTUPDATEDELETE 语句。 添加这些语句后,我们可以利用 GridView、DetailsView 和 FormView 控件固有的插入、编辑和删除功能。

编程愉快!

关于作者

Scott Mitchell 是七本 ASP/ASP.NET 书籍的作者, 4GuysFromRolla.com 的创始人,自 1998 年以来一直从事 Microsoft Web 技术工作。 Scott 担任独立顾问、培训师和作家。 他的最新书是 山姆斯在24小时内 ASP.NET 2.0自学。 可以在 上联系 mitchell@4GuysFromRolla.com他, 也可以通过他的博客联系到他,该博客可在 http://ScottOnWriting.NET中找到。

特别感谢

本教程系列由许多有用的审阅者查看。 本教程的主要审阅者是 Scott Clyde、Randell Schmidt 和 Ken Pespisa。 有兴趣查看我即将发布的 MSDN 文章? 如果是,请在 处放置一行 mitchell@4GuysFromRolla.com。