ASP.NET 2.0数据教程:创建数据访问层

开发 后端
本文介绍了在asp.net 2.0中如何创建一个数据访问层(DAL)的第二步。

创建一个数据访问层

与数据打交道时,一种做法是把跟数据相关的逻辑直接放在表现层中(在一个web应用里,asp.net网页构成了表现层)。其形式一般是在asp.net 网页的编码部分写ADO.NET 编码或者在标识符部分使用SqlDataSource控件。在这两种形式里,这种做法都把数据访问逻辑与表现层紧密耦合起来了。但推荐 的做法是,把数据访问逻辑从表现层分离开来。这个分开的层被称作是数据访问层,简写为DAL,一般是通过一个单独的类库项目来实现的。这种分层框架的好处在很多文献里都有阐述(详见本教程***的“附加读物”里的资源),在本系列中我们将采用这种方法。

跟底层数据源相关的所有编码,譬如建立到数据库的连接,发出SELECT,INSERT ,UPDATE,和DELETE命令等的编码,都应该放置在DAL中。表现层不应该包含对 这些数据访问编码的任何引用,而应该调用DAL中的编码来作所有的数据访问请求。数据访问层包含访问底层数据库数据的方法。譬如,Northwind数据库中,有Products和Categories两个表,它们记录了可供销售的产品以及这些产品所属的分类。在我们的DAL中,我们将有下面这样的方法:

GetCategories(), 返回所有分类的信息

GetProducts(), 返回所有产品的信息

GetProductsByCategoryID(categoryID), 返回属于指定分类的所有产品的信 息

GetProductByProductID(productID), 返回指定产品的信息

这些方法,被调用后,将连接到数据库,发出合适的查询,然后返回结果。我们如何返回这些结果是很重要的。这些方法可以直接返回数据库查询填充的DataSet 或者DataReader ,但理想的办法是把这些结果以强类型对象的形式返回。一个强类型的对象,其schema是编译时严格定义好的,而相比之下,弱类型的对象,其schema在运行时之前是未知的。

譬如,DataReader和普通的DataSet是弱类型对象,因为它们的schema是被用来填充它们的数据库查询返回的字段来定义的。要访问弱类型DataTable中的一个特定字段,我们需要用这样的句法:DataTable.Rows[index] ["columnName"]。这个例子中的DataTable的弱类型性质表现在于,我们需要通过一个字符串或序号索引来访问字段名称。而在另一个方面,一个强类型的DataTable,它的所有的字段都是通过属性的形式来实现的,访问的编码就会象这样:DataTable.Rows[index].columnName。

要返回强类型对象,开发人员可以创建自定义业务对象,或者使用强类型的DataSet。开发人员实现的业务对象类,其属性往往是对相应的底层数据表的字段的映射。而一个强类型的DataSet,则是Visual Studio基于数 据库schema为你生成的一个类,其成员的类型都是由这个schema决定的。强类型的DataSet本身,是由继承 于ADO.NET中DataSet,DataTable,和DataRow类的子类组成的。除了强类型的DataTable外,强类型的DataSet现在还包括TableAdapter类,这些类包含了填充DataSet中的DataTable和把 DataTable的改动传回数据库的各种方法。

注意:想了解使用强类型DataSet比之业务对象的优缺点的更多信息,请参考设计数据层组件以及在层间传输数据一文

在这些教程的架构里,我们将使用强类型的DataSet。图3示范说明了使用强类型的DataSet之应用程序的不同层间的流程(workflow)。

把所有的数据访问编码委托给DAL 

图 3: 把所有的数据访问编码委托给DAL

创建数据访问层:创建强类型的DataSet和Table Adapter

我们开始创建我们的DAL,先给我们的项目添加一个强类型的DataSet。做法如下,在解决方案管理器里的项目节点上按右鼠标,选择“添加新项(Add a New Item)”。在模板列单里选择DataSet,将其命名为Northwind.xsd。

给你的项目添加一个新的DataSet 

图 4: 给你的项目添加一个新的DataSet

在点击“添加(Add)”按钮后,Visual Studio会问我们是否将DataSet添加到App_Code文件夹中,选择“Yes” 。然后Visual Studio会显示强类型的DataSet的设计器,同时会启动TableAdapter配置向导,允许你给你的强 类型DataSet添加***个TableAdapter。

强类型的DataSet 起了强类型对象的集合的作用,它由强类型DataTable实例组成,每个强类型DataTable又进 而由强类型的DataRow实例组成。我们将为这个教程系列要用到的每个数据表建立一个对应的强类型DataTable 。让我们开始吧,先为Products表建立一个DataTable。

记住,强类型的DataTable并不包括如何访问对应底层的数据表的任何信息。要获取用来填充DataTable的数据 ,我们使用TableAdapter类,它提供了数据访问层的功能。对于我们的Products DataTable,相应的TableAdapter 类将包 括GetProducts()和GetProductByCategoryID(categoryID)等方法,而我们将在表现层调用这些方法。DataTable的作用是在分层间传输数据。

TableAdapter配置向导首先要你选择使用哪个数据库。下拉框里列出了服务器资源管理器内的那些数据库。如果你预先没有把Northwind数据库添加到服务器资源管理器里去的话,这时你可以点击新连接按钮来添加。

在下拉框里选择Northwind数据库 

图 5: 在下拉框里选择Northwind数据库

选择好数据库后,按“下一步”按钮,向导会问你是否想在Web.config文件里存放连接字符串。将连接字符串存放在Web.config文件里,你可以避免把连接字符串硬写在TableAdapter类的编码中,如果将来连接字符串信息改动的话,这种做法会极大地简化要做的编码改动。如果你选择在配置文件存 放连接字符串,连接字符串将被置放于段落中,这个段落可以被加密来提高安全,也可以通过IIS 图形界面管理工具中的新的asp.net 2.0属性页来修改。当然这个工具更适于管理员。

在Web.config中存放连接字符串 

图6: 在Web.config中存放连接字符串

创建数据访问层的下一步,我们需要定义***个强类型的DataTable的schema,同时为用来填充强类型DataSet的TableAdapter类提供***个方法。这两步可以通过建立一个返回对应于DataTable的数据表的字段的查询同时完成。在向导的***,我们将为这个查询对应的方法命名。完成后,这个方法可以在表现层调用,它会执行设置好的查询,进而填充一个强类型的DataTable。

开始定义SQL查询之前,我们必须首先选择我们想要TableAdapter执行查询的方式。我们可以直接用ad-hoc的SQL语句,或建立一个新的存储过程,或使用现存的存储过程。在这些教程里,我们将使用ad-hoc的SQL语句。请参考Brian Noyes的文章“使用Visual Studio 2005 DataSet 设计器创建数据访问层”中使用存储过程的例子。

用SQL语句查询数据 

图 7: 用SQL语句查询数据

至此,我们可以手工输入SQL查询。当生成TableAdapter的***个方法时,你一般想要让你的查询返回那些需要在对应的DataTable中存放的字段。我们可以建立一个从Products表里返回所有字段,所有数据行的查询来达到我们的目的:

在文本框里输入SQL查询 

图 8: 在文本框里输入SQL查询

或者,我们可以使用查询生成器(Query Builder),用图形界面来构造查询,如图9所示。

通过查询编辑器生成查询 

图 9: 通过查询编辑器生成查询

在生成查询之后,在移到下一屏之前,点击“高级选项(Advanced Options)”按钮。在网站项目里,在默认 情形下,“生成插入,更新,删除语句”是唯一已被选中的选项。如果你在类库项目或Windows项目里运行这个向导的话,“采用优化的并发控制(optimistic concurrency)”选项也会被选中。现在先别选“采用优化的并发 控制”这个选项。在以后的教程里我们会详细讨论优化的并发控制。

只选“生成插入,更新和删除语句”这个选项 

图 10: 只选“生成插入,更新和删除语句”这个选项

在核实高级选项后,按“下一步(Next)”按钮转到***一屏。在这里,配置向导会问我们要给TableAdapter选择添加什么方法。填充数据有两种模式:

填充DataTable – 这个做法会生成一个方法,该方法接受一个DataTable的参数,基于查询的结果填充这个DataTable。譬如,ADO.NET的DataAdapter类就是在它的Fill()方法中实现这个模式的 。

返回DataTable – 这个做法会生成一个方法,该方法会创建并填充一个DataTable,然后将 其作为方法的返回值。

你可以让TableAdapter实现其中一个模式或者同时实现两个模式。你也可以重新命名这里提供的这些方法。让 我们对两个复选框的选项不做改动,虽然我们在这些教程里只需要使用后面这个模式。同时,让我们把那个很 一般性的GetData方法名改成GetProducts。

这***一个复选框,“生成DB直接方法(GenerateDBDirectMethods)”,如果选了的话,会为TableAdapter自动生 成Insert(),Update(),和Delete()方法。如果你不选这个选项的话,所有的更新都需要通过TableAdapter唯一的Update()方法来实现,该方法接受一个强类型的DataSet,或者一个DataTable,或者单个DataRow,或者一个DataRow数组。(假如你 在图9所示的高级属性里把“生成添加,更新和删除语句”的选项去掉的话,这个复选框是不起作用的)。让我们保留这个复选框的选项。

把方法名字从 GetData 改成 GetProducts 

图 11: 把方法名字从 GetData 改成 GetProducts

按“完成”按钮结束向导。在向导关闭后,我们回到DataSet设计器中,它会显示我们刚创建的DataTable。你可以看到Products DataTable的字段列单(ProductID, ProductName 等),还有ProductsTableAdapter的Fill()和GetProducts()方法 。

Products DataTable和ProductsTableAdapter被添加到强类型DataSet中 

图 12: Products DataTable和ProductsTableAdapter被添加到强类型DataSet中

至此,我们生成了含有单一DataTable类(Northwind.Products)的强类型DataSet以及一个含 有GetProducts()方法的强类 型DataAdapter类(NorthwindTableAdapters.ProductsTableAdapter)。通过这些对象可以用下 列编码来获取所有产品的列单:

  1. NorthwindTableAdapters.ProductsTableAdapter   
  2.  
  3. productsAdapter = new   
  4.  
  5. NorthwindTableAdapters.ProductsTableAdapter();  
  6. Northwind.ProductsDataTable products;  
  7.  
  8. products = productsAdapter.GetProducts();  
  9.  
  10. foreach (Northwind.ProductsRow productRow in products)  
  11.     Response.Write("Product: " +   
  12.  
  13. productRow.ProductName + "");  
  14.  

这段编码不要求我们写一行的跟数据访问有关的编码。我们不需要生成任何ADO.NET类的实例,我们不需要 指明任何连接字符串,任何SQL查询语句,或者任何存储过程。TableAdapter为我们提供了底层的数据访问编 码!

这个例子里的每个对象都是强类型的,允许Visual Studio提供IntelliSense帮助以及编译时类型检查。最棒 的是,从TableAdapter 返回的DataTable可以直接绑定到asp.net数据Web 控件上去,这样的控件包 括GridView,DetailsView,DropDownList,CheckBoxList,以及另外几个控件。下面这个例子示范只要 在Page_Load事件处理函数里添加短短的三行编码就能将从GetProducts()方法返 回的DataTable绑定到一个GridView上去。

AllProducts.aspx

asp.net 

  1.  < %@ Page Language="C#"   
  2.  
  3. AutoEventWireup="true" CodeFile="AllProducts.aspx.cs"   
  4.  
  5. Inherits="AllProducts" %>  
  6.  
  7. < !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0   
  8.  
  9. Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  10.  
  11. < html xmlns="http://www.w3.org/1999/xhtml" >  
  12. < head runat="server">  
  13.     < title>View All Products in a GridViewtitle>  
  14.     < link href="Styles.css"   
  15.  
  16. rel="stylesheet"   
  17.  
  18. type="text/css"   
  19.  
  20. />  
  21. head>  
  22. < body>  
  23.     < form id="form1" runat="server">  
  24.     < div>  
  25.         < h1>  
  26.             All Productsh1>  
  27.         < p>  
  28.             < asp:GridView ID="GridView1" runat="server" 
  29.              CssClass="DataWebControlStyle">  
  30.                < HeaderStyle CssClass="HeaderStyle" />  
  31.                < AlternatingRowStyle CssClass="AlternatingRowStyle" />  
  32.             asp:GridView>  
  33.              p>  
  34.  
  35.     div>  
  36.     form>  
  37. body>  
  38. html>  
  39.  

AllProducts.aspx.cs

  1. using System;  
  2. using System.Data;  
  3. using System.Configuration;  
  4. using System.Collections;  
  5. using System.Web;  
  6. using System.Web.Security;  
  7. using System.Web.UI;  
  8. using System.Web.UI.WebControls;  
  9. using System.Web.UI.WebControls.WebParts;  
  10. using System.Web.UI.HtmlControls;  
  11. using NorthwindTableAdapters;  
  12.  
  13. public partial class   
  14.  
  15. AllProducts : System.Web.UI.Page  
  16. {  
  17.     protected void   
  18.  
  19. Page_Load(object sender, EventArgs e)  
  20.     {  
  21.         ProductsTableAdapter productsAdapter = new 
  22.          ProductsTableAdapter();  
  23.         GridView1.DataSource = productsAdapter.GetProducts();  
  24.         GridView1.DataBind();  
  25.     }  
  26. }  
  27.  

显示在GridView里的产品列单  

图 13: 显示在GridView里的产品列单

这个例子要求我们在asp.net网页的Page_Load事件处理函数里,写三行编码。在以后的教程里,我们将讨论使用ObjectDataSource,用声明的方式来从DAL中获取数据。用ObjectDataSource的话,我们一行编码都不用写,而且还能得到分页和排序支持呢!

【编辑推荐】

  1. 如何在IIS6.0中部署asp.net mvc程序
  2. 用Winform傻瓜式搭建asp.net mvc框架
  3. ASP.NET Session失效的编程思路
  4. ASP.NET Session 状态的存储
  5. 了解ASP.NET Web应用程序模型

 

责任编辑:book05 来源: 博客堂
相关推荐

2009-07-24 14:15:51

数据访问层

2009-07-24 12:41:21

BLL类

2009-07-24 16:37:04

创建母版页asp.net 2.0

2009-07-24 13:45:28

添加参数化

2009-08-19 10:54:42

ASP.NET数据访问

2009-07-27 16:09:05

GridView显示数

2009-07-24 17:15:52

SiteMapData

2009-07-27 09:35:57

业务逻辑层

2009-07-24 13:07:59

BLL类

2009-08-04 10:17:55

ASP.NET SqlASP.NET数据访问

2009-07-27 03:21:00

breadcrumb导

2009-07-27 16:22:54

GridView选择行

2009-07-27 09:01:44

ObjectDataS

2009-07-24 17:08:31

添加站点地图asp.net

2009-07-20 17:12:17

ASP.NET访问数据

2009-07-27 09:39:04

SelectMetho

2009-07-27 09:28:55

TableAdapte

2009-07-23 14:43:24

数据源控件ASP.NET 2.0

2009-07-22 17:21:27

ASP.NET 2.0

2009-07-28 14:06:28

ASP.NET 2.0
点赞
收藏

51CTO技术栈公众号