SqlDataSource控件

来源:互联网 发布:画装修图软件 编辑:程序博客网 时间:2024/04/28 12:06

 

如果数据存储在SQL Server、SQL Server Express、Oracle Server、ODBC数据源、OLE DB数据源或Windows SQL CE数据库中,就应使用SqlDataSource控件。该控件提供了一个易于使用的向导,引导用户完成配置过程,也可以通过直接在Source视图中修改控件的属性,手动修改控件。在本节前面的例子中,使用向导创建了一个SqlDataSource控件,并配置了它。完成配置后,就可以查看它生成的源代码了。

在Visual Studio Web站点项目中打开一个.aspx页面,把SqlDataSource控件从工具箱拖放到窗体上,就创建了一个SqlDataSource控件。Visual Studio工具箱分为各个功能组,在Data组中可以找到所有与数据相关的控件。

1. 配置数据连接

把控件拖放到Web页面上后,就要告诉它应使用什么连接。最简单的方式是使用Configure Data Source向导,如图7-2所示。从数据源控件的智能标记菜单中选择Configure Data Source选项,启动这个向导。

打开向导后,就应创建与SQLServer中的Northwind数据库的连接。这个连接将用于本章的大多数例子。

提示:

自从Microsoft SQLServer 2005以来,Microsoft不再把Northwind示例数据库包含为默认安装的一部分。但仍可以从下述位置下载这个示例数据库的安装脚本:

http://www.microsoft.com/downloads/details.aspx?FamilyId=06616212-0356-46A0-8DA2-EEBC53A68034&displaylang=en

                             

向导打开后,可以从下拉列表中选择已有的连接,或者创建新连接。如果单击New Connection按钮,就会打开ConnectionProperties对话框,如图7-3所示。在这个对话框中可以设置新数据库连接的所有属性。

单击Change按钮,在这里可以选择该连接使用的特定数据提供程序。控件默认使用ADO.NET SQL数据提供程序,还可以使用Oracle、OLE DB、ODBC和SQL Server Mobile Edition提供程序。

提示:

提供程序列表是从machine.config文件的DbProviderFactory节点中包含的数据生成的。如果要在向导中显示其他提供程序,可以修改machine.config文件,以包含特定提供程序的信息。

接着,给数据库连接填充相关的信息。单击TestConnection按钮,验证连接信息是否正确,然后单击OK按钮返回向导。

返回到Data SourceConfiguration向导后,注意刚才创建的连接现在出现在可用连接下拉列表中。从下拉列表中选择一个连接字符串后,连接信息就会显示在Data Connection信息区域中。这将便于在下拉列表中查看所选连接的信息。

单击Next按钮,继续执行向导的下一步。向导接着要求用户选择是否在web.config文件中保存连接信息,以便于维护和部署应用程序。这个屏幕允许指定连接信息在配置文件中存储时使用的关键字。如果选择不在web.config文件中存储连接信息,它们就在.aspx页面上存储为SqlDataSource控件的一个属性。如果所选的提供程序不是SQLDate Provider,就使用ProviderName属性存储该设置。

向导下一步要求配置数据源控件用于从数据库中检索数据的SELECT语句。这个屏幕如图7-4所示,提供了一个下拉列表,其中包含连接信息中指定的数据库中的所有可用表和视图。选择了一个表或视图后,就可以从列表框中选择要包含在查询中的列。可以使用星号(*)选择所有的列,也可以给每个列名旁边的复选框加上标记,来选择某些列。单击WHERE或ORDER BY按钮,还可以为查询指定用于过滤的WHERE子句参数和用于排序的ORDER BY参数。目前不需要输入WHERE或ORDER BY参数。

最后,Advanced按钮包含两个高级选项。可以让向导根据所创建的SELECT语句,为数据生成INSERT、UPDATE和DELETE语句。还可以把数据源控件配置为使用Optimistic Concurrency,以防止出现数据并发问题。

OptimisticConcurrency是一个数据库技术,有助于防止对数据的无意覆盖。启用Optimistic Concurrency时,SqlDataSource控件使用的Update和Delete SQL语句就会修改为包含初始值和更新值。执行查询时,目标记录中的数据会与SqlDataSource控件的初始值比较,如果它们有区别,就提示自从SqlDataSource控件提取出数据以来,这些数据有变化,不执行Update或Delete。

该向导的最后一个屏幕是预览数据源控件选择的数据,以验证查询是否按照希望的那样执行。单击Finish按钮结束该向导。

在配置完数据连接后,就可以看到SqlDataSource控件的外观了。切换到Visual Studio的Source视图中,看看向导为控件生成了什么属性,如程序清单7-2所示。

程序清单7-2 Visual Studio生成的典型SqlDataSource控件

 

  

<asp:SqlDataSource  ID="SqlDataSource1" Runat="server"
  SelectCommand="SELECT * FROM [Customers]"
  ConnectionString="<%$ ConnectionStrings:AppConnectionString1  %>">
  </asp:SqlDataSource>

 

可以看出,该控件使用声明语法,通过创建ConnectionString属性来配置它使用的连接,并通过创建SelectCommand属性来指定要执行的查询。本章的后面将介绍如何把SqlDataSource控件配置为在数据变化时执行INSERT、UPDATE和DELETE命令。

2. DataSourceMode属性

SqlDataSource控件的一个重要属性是DataSourceMode。这个属性可以告诉控件,在检索数据时,是使用DataSet还是使用DataReader。在设计数据驱动的ASP.NET页面时,这是很重要的。如果选择使用DataReader,就使用所谓的消防水龙带(firehose)模式来检索数据,即只前向的只读光标。这是从数据源中读取数据的最快方式,因为DataReader没有DataSet所需要的内存和处理开销。但选择使用DataSet可以使数据源控件变得更强大,能执行过滤、排序或分页等其他操作。它还支持控件内置的高速缓存功能。每个选项都有各自的优缺点,所以在设计Web站点时要仔细考虑这个属性。该属性的默认值是使用DataSet检索数据。程序清单7-3中的代码演示了如何给SqlDataSource控件添加DataSourceMode属性。

程序清单7-3 给SqlDataSource控件添加DataSourceMode属性

  

<asp:SqlDataSource  ID="SqlDataSource1" Runat="server"
  SelectCommand="SELECT * FROM [Customers]"
  ConnectionString="<%$ ConnectionStrings:AppConnectionString1  %>"
  DataSourceMode="DataSet">
  </asp:SqlDataSource>

 

3. 使用SelectParameters过滤数据

当然,从数据源中选择数据时,不希望从视图或表中获取所有的数据,而希望在查询中指定参数,以限制返回的数据。为此,数据源控件可以使用SelectParameters集合创建参数,用于在运行时修改从查询中返回的数据。

SelectParameters集合由派生于Parameters类的类型组成。可以在该集合中合并任意多个参数。数据源控件将使用这些参数创建动态的SQL查询。表7-2描述了一些可用的参数类型。

表 7-2

  

参 数

   

描 述

   

ControlParameter

   

使用指定控件的属性值

   

CookieParameter

   

使用cookie 的关键字值

   

FormParameter

   

使用Forms集合中的关键字值

   

QuerystringParameter

   

使用Querystring集合中的关键字值

   

ProfileParameter

   

使用用户配置的关键字值

   

SessionParameter

   

使用当前用户的会话的关键字值

 

所有的参数都派生于Parameters类,所以它们都包含几个很有用的共有属性,这些属性如表7-3所示。

表 7-3

  

属 性

   

描 述

   

Type

   

可以强类型化参数的值

   

ConvertEmptyToNull

   

如果赋予控件的值是System.String.Empty,就应把它转换为Null

   

DefaultValue

   

如果参数的值是Null,就指定其默认值

 

程序清单7-4中的代码示例把一个QueryStringParameter控件添加到SqlDataSource控件的SelectParameters集合中。可以看出,SelectCommand查询修改为包含一个WHERE子句。运行这段代码时,查询字符串字段ID的值绑定到SelectCommand的@CustomerID占位符上,可以选择出CustomerID字段匹配查询字符串字段值的顾客。

程序清单7-4 使用SelectParameter控件过滤选中的数据

  

<asp:SqlDataSource  ID="SqlDataSource1" Runat="server"
  SelectCommand="SELECT * FROM [Customers] WHERE ([CustomerID] =  @CustomerID)"
  ConnectionString="<%$ ConnectionStrings:AppConnectionString1  %>"
  DataSourceMode="DataSet">
  <SelectParameters>
  <asp:QueryStringParameter Name="CustomerID"
  QueryStringField="ID" Type="String">
  </asp:QueryStringParameter>
  </SelectParameters>
  </asp:SqlDataSource>

 

除了手动编写SelectParameters集合之外,还可以使用Command andParameter Editor对话框创建参数,在设计模式下查看Web页面时,修改SqlDataSource控件的SelectCommand属性,就可以打开Command and ParameterEditor对话框,如图7-5所示。

4. ConflictDetection属性

ConflictDetection属性可以告诉SqlDataSource控件在更新数据时使用什么样式的冲突检测。如果多个用户尝试修改相同的数据,它确定了执行什么操作。其值设置为OverwriteChanges时,控件使用更新数据的Lastin Wins样式。在这个样式中,控件会在检索数据后、进行更新之前重写对数据的修改。

如果其值设置为CompareAllValues,数据源控件就会比较原始数据值(检索出来的值)和数据库中的当前数据值。如果数据自检索出来后未修改,控件就可以改变数据值。如果控件检测到从数据库中检索出来的原始数据值与数据库中的当前数据值不同,就不允许更新。当多个用户访问数据库,并修改数据时,就有可能发生这种情况。此时,在一个用户把修改的内容发送给数据库之前,另一个用户可能检索并修改了数据。如果不希望重写前一个用户的修改,就需要使用CompareAllValues值。程序清单7-5演示了如何给SqlDataSource控件添加ConflictDetection属性。

程序清单7-5 给SqlDataSource控件添加ConflictDetection属性

  

<asp:SqlDataSource  ID="SqlDataSource1" Runat="server"
  SelectCommand="SELECT * FROM [Customers] WHERE ([CustomerID] =  @CustomerID)"
  ConnectionString="<%$ ConnectionStrings:AppConnectionString1  %>"
  DataSourceMode="DataSet"
  ConflictDetection="CompareAllValues">
  <SelectParameters>
  <asp:QueryStringParameter Name="CustomerID"
  QueryStringField="id" Type="String">
  </asp:QueryStringParameter>
  </SelectParameters>
  </asp:SqlDataSource>

 

如前所述,也可以使用SqlDataSource控件配置向导给控件添加乐观并发控制。这么做会对底层的控件进行几处修改。首先,是给控件自动添加ConflictDetection属性,并把它设置为CompareAllValues。其次,向导会修改Update和Delete参数集合,以包含原始数据值参数。其三,修改SQL语句,以比较原始数据值和新值。新增的参数很容易识别,因为向导给每个数据列名都添加了前缀"original"。程序清单7-6列出了UpdateParameters的变化。

程序清单7-6 给UpdateParameters集合添加原始值参数

  

<UpdateParameters>
  <asp: Parameter Name="CompanyName" Type="String" />
  <asp: Parameter Name="ContactName" Type="String" />
  <asp: Parameter Name="ContactTitle" Type="String"  />
  <asp: Parameter Name="Address" Type="String" />
  <asp: Parameter Name="City" Type="String" />
  <asp: Parameter Name="Region" Type="String" />
  <asp: Parameter Name="PostalCode" Type="String" />
  <asp: Parameter Name="Country" Type="String" />
  <asp: Parameter Name="Phone" Type="String" />
  <asp: Parameter Name="Fax" Type="String" />
  <asp: Parameter Name="original_CustomerID"  Type="String" />
  <asp: Parameter Name="original_CustomerName"  Type="String" />
  <asp: Parameter Name="original_ContactName"  Type="String" />
  <asp: Parameter Name="original_ContactTitle"  Type="String" />
  <asp: Parameter Name="original_Address" Type="String"  />
  <asp: Parameter Name="original_City" Type="String"  />
  <asp: Parameter Name="original_Region" Type="String"  />
  <asp: Parameter Name="original_PostalCode"  Type="String" />
  <asp: Parameter Name="original_Country" Type="String"  />
  <asp: Parameter Name="original_Phone" Type="String"  />
  <asp: Parameter Name="original_Fax" Type="String"  />
  </UpdateParameters>

 

最后,SqlDataSource向导设置了另一个属性OldValueParameterFormatString。这个属性确定原始数据值的前缀,它默认为"original_0",但可以改变它。

确定更新是否遇到并发错误的一种方式是在SqlDataSources的Updated事件中测试AffectedRows属性。程序清单7-7演示了一种方式。

程序清单7-7 在更新数据后检测并发错误

  

VB
  Protected Sub SqlDataSource1_Updated(ByVal sender As Object, _
  ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs)
  If (e.AffectedRows > 0) Then
  Message.Text = "The record has been updated"
  Else
  Message.Text = "Possible concurrency violation"
  End If
  End Sub
  C#
  protected void SqlDataSource1_Updated(object sender,
  SqlDataSourceStatusEventArgs e)
  {
  if (e.AffectedRows > 0)
  Message.Text = "The record has been updated";
  else
  Message.Text = "Possible concurrency violation";
  }

 

5. SqlDataSource事件

SqlDataSource控件提供了许多事件,它们可以影响SqlDataSource控件的行为,或对执行SqlDataSource控件时发生的事件作出响应。该控件提供的事件在执行Select、Insert、Update和Dalete命令的前后触发。使用这些事件可以改变控件发送给数据源的SQL命令。在执行SQL命令时,也可以取消操作,或确定是否发生了错误。

6. 用数据源事件处理数据库错误

数据源控件的事件非常适合于捕获和处理在对数据库执行SQL命令时发生的错误。例如,程序清单7-8演示了如何使用SqlDataSource控件的Updated事件处理作为异常返回给应用程序的数据库错误。

程序清单7-8 用SqlDataSource控件的Updated事件处理数据库错误

  

VB
  Protected Sub SqlDataSource1_Updated(ByVal sender As Object, _
  ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs)
  If (e.Exception IsNot Nothing) Then
  'An exception has occurring executing the
  'SQL command and needs to be handled
  lblError.Text = e.Exception.Message

 

         'Finally, tell ASP.NET you have  handled the
  'exception and it is to continue
  'executing the application code
  e.ExceptionHandled = True
  End If
  End Sub
  C#
  protected void SqlDataSource1_Updated(object sender,
  System.Web.UI.WebControls.SqlDataSourceStatusEventArgs e)
  {
  if (e.Exception != null)
  {
  //An exception has occurring executing the
  //SQL command and needs to be handled
  lblError.Text = e.Exception.Message;

 

         //Finally, tell ASP.NET you have  handled the
  //exception and it is to continue
  //executing the application code
  e.ExceptionHandled = true;
  }
  }

 

注意该示例测试Exception属性是否为null;如果不是(表示发生了异常),应用程序就尝试处理该异常。

这个示例的一个要点是设置ExceptionHandled属性的代码。这个属性默认返回False。因此,即使检测到Exception属性不为空,并尝试处理错误,该异常仍会返回给应用程序。把ExceptionHandled属性设置为True,就告诉.NET已成功地处理了异常,应用程序可以安全地继续执行。注意,AccessDataSource和ObjectDataSource控件都以这种方式执行。

SqlDataSource控件非常强大,但还有许多其他数据源控件,更适合于特定的数据访问场合。


7.将SqlDataSource用于Oracle

与前面使用SqlDataSource控件连接Microsoft的SQL Server一样,还可以将这个控件用于连接企业中的其他数据库,例如Oracle 数据库。

要将SqlDataSource控件用于Oracle,首先要把SqlDataSource控件拖放到页面的设计界面上。使用SqlDataSource控件的智能标记,单击ConfigureData Source链接,就可以配置数据源。

在Configure DataSource向导中,首先要创建与Oracle数据库的一个新连接。单击NewConnection按钮,打开Add Connection对话框,如图7-6所示。

数据源默认配置为使用SQL Server数据库。要改变这个默认设置,可以单击Change按钮。打开一个新的对话框,可以在该对话框中选择Oracle选项。这个对话框如图7-7所示。

选择Oracle数据库,会改变Add Connection对话框,使之更便于完成后面的工作,如图7-8所示。

在Add Connection对话框中,可以在Server name文本框中添加要连接的Oracle数据库名。在此,这个名称就是tnsnames.ora配置文件中包含的数据库名。在要连接Oracle的服务器上安装Oracle Client后,该文件会自动生成。该文件一般位于OracleClient软件版本专用的文件夹结构中,例如C:\Oracle\product\10.1.0\Client_1\NETWORK\ADMIN。在这个tnsnames.ora文件中,一个数据库项如下所示:

  

MyDatabase =
  (DESCRIPTION =
  ADDRESS_LIST =
  (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.101)(PORT = 1521))
  )
  (CONNECT_DATA =
  (SID = MyDatabase)
  (SERVER = DEDICATED)
  )
  ) 

 

引用了数据库后,就可以使用数据库用户名和密码,再像操作SQL Server那样使用SqlDataSource控件了。完成了SqlDataSource的配置后,在web.config文件的<connectionString>段中就会有一个对Oracle的新连接(假定通过配置过程选择在web.config文件中保存连接字符串),如下所示:

  

<connectionStrings>
  <add name="ConnectionString"
  connectionString="Data Source=MyDatabase;
  User ID=user1;Password=admin1pass;Unicode=True";
  providerName="System.Data.OracleClient" />
  </connectionStrings>