asp.net 2.0-实现数据访问(1)

 

几乎所有的动态web应用程序都涉及到数据访问,幸运的是ASP.NET 2.0使这个过程变得非常容易。在1.0中开发者需要写额外的代码来获取数据绑定服务器控件,而在2.0中能大多数的场合下,我们只需要使用数据访问控件来自动完成这些过程:

 

1、获取显示数据

2、排序、分页、缓存数据

3、增加、删除、修改数据

4、使用参数过滤和显示主从数据

 

ASP.NET 2.0引进了两种服务器控件来参与这个数据绑定模型。这两种数据控件能处理负责的数据体系,能适用大多的请看,开发者不需要知道任何页面的事件与周期,仅仅需要做的只是绑定到控件。还有一个好处是可以方便的进行扩展,为不同的数据源提供有力的支持。

 

数据源控件

 

数据源控件可以在不渲染的情况下表现多种复杂的数据源,比如业务逻辑、XML文件、WEB服务。而且数据库控件还可以方便得进行数据排序、分页、过滤、修改、删除、插入得操作,和数据绑定控件配合在一起能自动完成上述操作过程。

 

控件名

描述

SqlDataSource

能绑定使用ASP.NET Provider访问的MSSQLOLEDBODBCORACLE等数据平台

ObjectDataSource

能绑定中间层得数据,比如业务逻辑、数据访问层等

AccessDataSource

能绑定ACCESS文件数据库

SiteMapDataSource

能绑定ASP.NET 2.0 导航Provider提供的层次数据

XmlDataSource

能绑定XML 文件

 

数据绑定控件

 

数据绑定控件用来呈现数据,根据客户端获取请求调整数据的呈现。数据绑定控件能在适当的页面生命周期内自动绑定并且呈现数据,而且这些控件能有效的和数据访问控件结合完成一些诸如分页排序过滤等功能,数据绑定控件通过DataSourceID等属性来和数据源控件进行关联,你可能熟悉1.0DataFridDataListDropDownList等控件,而2.0中又提供了一些新的控件:

 

控件名

描述

GridView

用网格形式呈现数据,是1.0DataGrid的增强版本,能有效的和数据源控件配合自动完成一些操作

DetailsView

用标签/数据的形式在表格中呈现某一项数据,和ACCESS中的表单视图差不多,同样也能有效的和数据源控件配合自动完成一些操作

FormView

用标签/数据的形式根据自定义的模板在表格中呈现某一项数据,和ACCESS中的表单视图差不多,同样也能有效的和数据源控件配合自动完成一些操作

TreeView

用树型层次可展开收缩结构展现数据

Menu

用分层的动态菜单表现数据

 

下面的例子示范了一些上述的新特性:

 

一、绑定数据库

 

从诸如MSSQLORACLE、或者其他OLEDBODBC数据源中获取数据是在WEB程序中常用的数据形式。SqlDataSource控件直接和数据库连接为数据绑定控件自动进行一些数据操作做数据源,有了它你可以不用在代码里面写连接数据库语句或者查询语句了,因为你可以直接通过属性在数据源控件中指定查询语句,这种其实是一种双重的模式,因为其实还是在通过代码在进行数据访问,因此,可能这仅仅只适合没有大数据量的个人的小型站点或者个人爱好来使用下。还有一种ObjectDataSource控件用来和大型企业开发中的中间层业务逻辑封装进行数据操作,接下来的章节会讨论到。

 

GridView 控件

 

下面的例子使用GridView控件从数据库绑定数据,用表格来呈现行列数据,纵向的记录、横向的字段,如果你熟悉DataGrid的话可以发现他们有非常相似的地方。GridView控件提供以下特性:

 

1、和数据源控件绑定

2、内建排序机制

3、内建删除修改机制

4、内建分页机制

5、内建行选择机制

6、动态为GridView设置属性和操作一些事件

7、新增了一些诸如CheckBosFieldImageField等的列

8、链接列能绑定多个字段的数据

9、能使用多个字段作为主键字段

10、通过主题和CSS自定义样式

 

建立数据报表

最简单的数据表格,只能显示数据而不能进行修改操作,要实现这样的报表呈现MSSQL数据先在页面上使用SqlDataSource然后设置GridViewDataSourceID属性来和数据源关联,下面是例子:

 

<form runat="server">

  <asp:GridView ID="GridView1" DataSourceID="SqlDataSource1" runat="server"/>

  <asp:SqlDataSource ID="SqlDataSource1" runat="server"

    SelectCommand="SELECT [au_id], [au_lname], [au_fname] FROM [authors]"

    ConnectionString="<%$ ConnectionStrings:Pubs %>" />

</form>

 

SqlDataSourceConnectionString属性指定了数据库的连接字符串,SelectCommand属性指定了获取数据的查询语句,你可以在页面上写连接字符串,这个例子我们在web.config中按照一定的格式来指定。SqlDataSource控件不只是可以连接到MSSQL数据库,它能连接到任何ASP.NET System.Data.Common.DbProviderFactory 指定的一些数据库,默认在machine.config包含了如下四种。

 

<configuration>

  <system.data>

    <DbProviderFactories>

      <add name="Odbc Data Provider" invariant="System.Data.Odbc" type="System.Data.Odbc.OdbcFactory, ..." />

      <add name="OleDb Data Provider" invariant="System.Data.OleDb" type="System.Data.OleDb.OleDbFactory, ..." />

      <add name="OracleClient Data Provider" invariant="System.Data.OracleClient" type="System.Data.OracleClient.OracleClientFactory, ..." />

      <add name="SqlClient Data Provider" invariant="System.Data.SqlClient" type="System.Data.SqlClient.SqlClientFactory, ..." />

    </DbProviderFactories>

  </system.data>

</configuration>

 

可以使用SqlDataSourceProviderName来指定任意一项固定的Provider,默认的是SqlClient,需要注意的是如果你改变了ProviderName,同样你也要确保你的SQL语句符合相应的数据源。

 

在下面的例子中,显示了使用绑定列和CheckBox列来呈现数据,当然你可以试试

ImageField, HyperLinkField, CommandField, ButtonField, TemplateField

 

  <asp:GridView ID="GridView1" DataSourceID="SqlDataSource1" AutoGenerateColumns="False"
      runat="server">
      <Columns>
        <asp:BoundField HeaderText="ID" DataField="au_id" ReadOnly="true" />
        <asp:BoundField HeaderText="Last Name" DataField="au_lname" />
        <asp:BoundField HeaderText="First Name" DataField="au_fname" />
        <asp:BoundField HeaderText="Phone" DataField="phone" />
        <asp:BoundField HeaderText="Address" DataField="address" />
        <asp:BoundField HeaderText="City" DataField="city" />
        <asp:BoundField HeaderText="State" DataField="state" />
        <asp:BoundField HeaderText="Zip Code" DataField="zip" />
        <asp:CheckBoxField HeaderText="Contract" DataField="contract" />
      </Columns>
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
      SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]"
      ConnectionString="<%$ ConnectionStrings:Pubs %>" />

 

SelectCommand属性同样也能用存储过程

 

<asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="Ten Most Expensive Products"
      ConnectionString="<%$ ConnectionStrings:Northwind %>" SelectCommandType="StoredProcedure" />

 

默认情况下,数据源控件通过DataSet得到数据的,当然你可以修改为DataReader形式,如果这样的话你就不能启用排序机制,因为它是只读向前的,不过确实赢得了不少性能

 

<asp:SqlDataSource ID="SqlDataSource1" runat="server"
      ConnectionString="<%$ ConnectionStrings:Northwind %>" 
      SelectCommand="Ten Most Expensive Products"
      SelectCommandType="StoredProcedure"
      DataSourceMode="DataReader" />

                                                    

连接字符串设置

下面看下连接字符串在config文件中是如何配置的,在connectionStrings节点下配置了以后可以方便的在其他页面中使用了

 

<configuration>

  <connectionStrings>

    <add name="Pubs" connectionString="Server=(local);Integrated Security=True;Database=pubs;"

      providerName="System.Data.SqlClient" />

  </connectionStrings>

</configuration>

 

再看看连接MSSQL的连接字符串的配置

<configuration>
  <connectionStrings>
    <add name="Pubs" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=pubs;Persist Security Info=True"
      providerName="System.Data.SqlClient" />
    <add name="Northwind" connectionString="Server=(local)\SQLExpress;Integrated Security=True;Database=Northwind;Persist Security Info=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.web>
      <pages styleSheetTheme="Default"/>
  </system.web>
</configuration>

 

ASP.NET 2.0 提供了加密的连接字符串的设置,在以后的安全章节中会详细说到,先可以看下大概的情况

 

<configuration>
  <protectedData>
    <protectedDataSections>
      <add name="connectionStrings" provider="RsaProtectedConfigurationProvider"
        inheritedByChildren="false" />
</protectedDataSections>
  </protectedData>
  <connectionStrings>
    <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
      xmlns="http://www.w3.org/2001/04/xmlenc#">
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
          <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
          <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <KeyName>Rsa Key</KeyName>
          </KeyInfo>
          <CipherData>
            <CipherValue>408EYuABn0MbVxxN9CAHMFpkX36odWkolxVw0neiuBQ888tZbpf8S7TWfpWDC4uz000uhH0FuR3iYVQkbEZ0gEU+y5zDcVp3uVzzryr7P4h/fm1oH0RnDPeKcegAkkq1HaX0tu5c5wcFmIi2Qs4pTR8kjn30kYBfBIUg5AsdZCo=</CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>5lkgSgwPTYDx6OYlRxaSLZhJwhGgssjmtljt+5Fo3hYt+Mu35oN4L4ODoiFKXpL3Kkd5+E+hABZRSJyRQPvwa26+8YGK5tV03xTjMs4rQkTh55514jv85i+bmZjNLmbw41u8QyEYEo30uu2yChdNAjh3TEHuths9nDoqhkTzfn0sx4Hyd2xukFd037c7ZZYrTIsB+EWX9nhFXhC3tTdQrateyiOHiRgyA5tWKXea86u/IUyZhGyC2w3A/PbfJ+oAJHSRAh0YqR+mGlJDcGypwPv7laAXV0VN1H5dFzCgmF5KsUOLyBAMAk/TGPaoXJGsdTjM2zrEzx1/8PITLU/x6IDSN2V53DRn3uHDMoHXBa6n2V3giyxpAitC/A02qDYPxuuDdPSCS7DALh2FF4FhrcoXQVtKWq+yy3bsQG7wNbQ5b5wCopuoLnjGcPK3BAvyC43krxbyUDBzk8ZIJvo6/FDJn3Uz2mbDquFu80yfM3YyqLV/VFuk6PXQXgF/YcbszKUiBlybSMw5KE2ieWWBiVrWExWayAGw</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>
  <system.web>
      <pages styleSheetTheme="Default"/>
  </system.web>
</configuration>

 

你用以下的形式指定数据源控件的ConnectionStringasp.net会在运行时查找config文件进行获取<%$ ConnectionStrings:Pubs %>,如果你需要指定ProviderName的话用下面这个格式<%$ ConnectionStrings:Pubs.ProviderName %>

分页和排序

GridView的一个重要特点就是能自动的和数据源控件配合实现一些操作,在以前我们通常时需要写些代码来完成这个功能的,只有我们设置了数据源的DataSourceModeDataSet的时候才能排序,我们需要做的仅是设置AllowSortingtrue,在表头会有链接可以点击进行排序,其实使用的是DataVIew的排序机制,所以说一定要是设置数据源的DataSourceModeDataSet,至于ASC或者DESC排序这个就不需要考虑了,GridView会自动根据你选择的情况和数据源控件“沟通”。只要是数据源符合ICollection接口的你可以设置AllowPaging属性来启用分页机制,数据源如果设置为DataSet当然符合这个接口,但是如果是DataReader的话就不行了,下面是分页的例子:

<asp:GridView ID="GridView1" AllowSorting="true" AllowPaging="true" runat="server" DataSourceID="SqlDataSource1"
      AutoGenerateColumns="False">

 

你能通过设置PagerStyle或者PagerSettings来设置分页的样式,前者是指定分页的样式后者是分页的模式(数字分页或者前后翻页)、分页的位置和相关属性,下面是例子

  <PagerSettings Mode="NextPreviousFirstLast" Position="TopAndBottom" FirstPageImageUrl="~/Images/First.gif"
        LastPageImageUrl="~/Images/Last.gif" NextPageImageUrl="~/Images/Next.gif" PreviousPageImageUrl="~/Images/Prev.gif" />
      <PagerStyle ForeColor="White" HorizontalAlign="Right" BackColor="#284775" />

 

需要注意的是,在前面的例子中,GridView的分页是基于SqlDataSource返回的DataView进行分页的,所以说,GridView控件得到的是所有的数据,提取一部分来显示到当前页面上,这中分页叫做表现层的分页,效率是相当差的,其实没有必要获取所有数据如果在数据源控件根据当前页面需要的数据返回就好了,可是SqlDataSource不支持这个特性,在以后的章节中我们可以看到ObjectDataSource支持这种分页机制。

 

更新和删除数据

 

和排序分页一样,GridView控件同样能够经过简单设置支持删除修改(关联的)数据,不过我们需要指定数据源控件的UpdateCommandDeleteCommand来实现,同样我们也可以为每一个字段用参数来指定,设置参数的输入/输出方向或者默认值,参数会在以后

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

  ConnectionString="<%$ ConnectionStrings:Pubs %>"

  SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors]"

  UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [state] = @state WHERE [au_id] = @au_id"

  DeleteCommand="DELETE FROM [authors] WHERE [au_id] = @au_id"/>

你可以设置GridViewAutoGenerateEditButtonAutoGenerateDeleteButton来启用修改删除,当然你也可以添加一个按钮列并且启用ShowEditButton或者ShowDeleteButton属性,GridView只支持每次修改删除一行数据,点击了修改按钮后行变成编辑行,点击修改提交数据,点击取消放弃修改。下面是修改的例子

<asp:GridView ID="GridView1" AllowSorting="true" AllowPaging="true" Runat="server"
        DataSourceID="SqlDataSource1" AutoGenerateEditButton="true" DataKeyNames="au_id"
        AutoGenerateColumns="False">
        <Columns>
          <asp:BoundField ReadOnly="true" HeaderText="ID" DataField="au_id" SortExpression="au_id" />
          <asp:BoundField HeaderText="Last Name" DataField="au_lname" SortExpression="au_lname" />
          <asp:BoundField HeaderText="First Name" DataField="au_fname" SortExpression="au_fname" />
          <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" />
          <asp:BoundField HeaderText="Address" DataField="address" SortExpression="address" />
          <asp:BoundField HeaderText="City" DataField="city" SortExpression="city" />
          <asp:BoundField HeaderText="State" DataField="state" SortExpression="state" />
          <asp:BoundField HeaderText="Zip Code" DataField="zip" SortExpression="zip" />
          <asp:CheckBoxField HeaderText="Contract" SortExpression="contract" DataField="contract" />
        </Columns>
      </asp:GridView>
      <asp:SqlDataSource ID="SqlDataSource1" Runat="server" SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone], [address], [city], [state], [zip], [contract] FROM [authors]"
        UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname, [au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] = @city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] = @au_id"
        ConnectionString="<%$ ConnectionStrings:Pubs %>" />

 

DataKeyNames这个属性是非常重要的,它指定了表的主建字段代表了某行,可以是多主建字段,DataKeyNames属性指定的字段会在视图状态中来回传递,修改删除的过程中,GridView传递根据特殊的数据字典中数据传递给数据源进行操作,你可以为某些绑定列设置ReadOnlytrue来禁止修改,这样的话这些数据就不会在字典中来回传递了,如果你用vs.net来添加GridView的话,主键字段的readonly属性会自动启用。需要注意的是如果你需要使用数据绑定控件的修改功能的话,你需要设定参数的名字和 实际字段的名字一致,但是如果主键字段也需要进行修改的话,我们需要来区分哪个数据是原来的哪个是修改后的,

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

  ConnectionString="<%$ ConnectionStrings:Pubs %>"

  SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors]"

  UpdateCommand="UPDATE [authors] SET [au_id] = @au_id, [au_lname] = @au_lname, [au_fname] = @au_fname, [state] = @state WHERE [au_id] = @original_au_id"

  DeleteCommand="DELETE FROM [authors] WHERE [au_id] = @original_au_id"/>

  OldValuesParameterFormatString="original_{0}"

 

在这个例子中,参数@original_au_id就是需要用到主键默认数据的参数,需要用OldValuesParameterFormatString来指定,如果你设置了ConflictDetection属性为CompareAllValues的话这个参数也可以对不是主键字段的数据起作用。

posted @ 2005-12-03 11:14  lovecherry  阅读(4608)  评论(2编辑  收藏  举报