创建数据访问层
本文档是 Visual Basic 教程 (切换到 Visual C# 教程)
该教程从头开始使用 Typed DataSet(强类型 DataSet)创建数据访问层 (DAL),以访问数据库中的信息。
« 前一篇教程 | 下一篇教程 »
简介作为 web 开发人员,我们的工作总是在和数据打交道。我们创建数据库来存储数据, 创建代码来检索并修改数据,并创建 Web 页面来收集和汇总数据。这是探讨在 ASP.NET 2.0 中 实现这些常用类型的技巧的系列教程中的首篇教程。 我们从创建一个软件架构开始,包括使用 Typed DataSet 的数据访问层 (DAL)、实现自定义业务规则的业务逻辑层 (BLL) 和共享同一页面布局的 ASP.NET 页面组成的表示层。一旦奠定了这个后端基础,我们接下来会转向报表,说明如何显示、汇总、收集和验证来自 Web 应用程序的数据。这些教程力求简明,使用大量屏幕截图逐步教您直观地了解整个流程。每个教程都提供 C# 和 Visual Basic 版本,并且可以下载所使用的全部代码。(这篇教程内容非常冗长,但接下来会分几大部分进行介绍,使人更容易理解和消化。) 针对这些教程,我们将使用放在 App_Data 目录下 Northwind 数据库的 Microsoft SQL Server 2005 Express Edition版。除数据库文件外,App_Data文件夹也包含创建该数据库的 SQL 脚本,以满足您想使用不同数据库版本的需求。如果愿意,这些脚本也可以直接从 Microsoft 下载如果您使用的是 Northwind 数据库的不同 SQL Server 版本,需要更新该应用程序的Web.config文件中的NORTHWNDConnectionString设置。这个 Web 应用程序是使用 Visual Studio 2005 Professional Edition 创建的基于文件系统的 Web 站点项目。不过,所有的这些教程同样适用于 Visual Studio 2005 免费版,即 Visual Web Developer。 该教程从头开始,先创建数据访问层(DAL),然后在第二篇教程中创建业务逻辑层(BLL)并在第三篇教程中进行 页面布局和导航。随后的教程以前三篇教程为基础。在这本教程中我们有很多内容要学习,现在就让我们打开Visual Studio 开始吧! 步骤 1:创建一个 Web 项目并连接到数据库在创建我们的数据访问层 (DAL) 之前,我们首先需要创建一个网站并安装我们的数据库。开始创建一个新的基于文件系统的 ASP.NET 网站:从 File 菜单选择 New Web Site,出现 New Web Site 对话框。选择 ASP.NET Web Site 模板,将 Location 下拉列表设置成 File System,然后为该网站选择一个文件夹,并将语言设置成 Visual Basic。 图1: 创建一个基于文件系统的新网站 这将创建一个具有Default.aspx页面、App_Data文件夹和Web.config文件的新网站。 创建好了网站,下一步是在 Visual Studio 的 Server Explorer 中添加对该数据库的引用。通过在 Server Explorer 中添加数据库,您可以添加来自 Visual Studio 的表、存储过程、视图等。您还可以手动或通过 Query Builder 直观地查看表数据或进行查询。而且,当我们为 DAL 创建 Typed DataSet 时,我们需要将 Visual Studio 指向需要建立 Typed DataSet 的数据库。当我们能够及时在那个点上提供这种连接信息时,Visual Studio 自动填充己在 Server Explorer注册过的数据库的下拉列表。 将 Northwind 数据库添加到 Server Explorer 的步骤取决于您是否愿意使用App_Data文件夹中的 SQL Server 2005 Express Edition 数据库,或者是否有您想使用的 Microsoft SQL Server 2000 或 2005 数据库服务器安装程序。 使用App_Data文件夹中的数据库如果您没有SQL Server 2000 或2005 数据库服务器可连接,或者您只想 避免将该数据库添加到数据库服务器的麻烦,可以使用位于已下载 网站的App_Data文件夹(NORTHWND.MDF) 的 Northwind 数据库的SQL Server 2005 Express Edition 版本。 位于App_Data文件夹中的数据库被自动添加到 Server Explorer。假如您安装了SQL Server 2005 Express Edition, 在 Server Explorer 应该看到一个名为 NORTHWND.MDF 的节点, 可以拓展并探究其表、视图、存储过程等(见图2)。 App_Data文件夹也可以存放Microsoft Access .mdb文件。 同它们的 SQL Server 版本的数据库一样,这类文件将被自动添加到 Server Explorer。如果您不想使用任何 SQL Server 的数据库,您可以 下载Northwind数据库文件的Microsoft Access 版本并加入App_Data目录。不过要记住,Access 数据库的特性不如 SQL Server丰富,且并不是为在网站环境下使用而设计的。另外, 35 以后的教程将用到某些不被 Access 支持的数据库级特性。 连接到 Microsoft SQL Server 2000 or 2005 数据库服务器中的数据库同样,您可能要连接到安装在数据库服务器上的Northwind数据库。如果数据库服务器还没有安装Northwind数据库,您必须先运行该教程下载文件中的安装脚本或直接从Microsoft网站下载 Northwind 的 SQL Server 2000 版本和安装脚本, 将其添加到数据库服务器。 一旦安装了该数据库,转到Visual Studio的Server Explorer,右键单击Data Connections节点并选择Add Connection。如果没有找到Server Explorer,转入View / Server Explorer或选择Ctrl+Alt+S。这时将出现Add Connection对话框,在这里可以指定要连接的服务器,认证信息和数据库名称。一旦成功配置了数据库连接信息,单击OK 按钮,该数据库将被作为一个节点添加到 Data Connections 节点下面。您可以展开该数据库节点以探究其表、视图、存储过程等。 图2: 在您的数据库服务器的 Northwind 数据库添加一个连接 步骤 2:创建数据访问层在处理数据时,有个选项是将数据的特定逻辑直接内嵌到表示层(Web 应用程序中,ASP.NET 页面组成表示层)。这可以通过在 ASP.NET 页面的代码部分编写 ADO.NET 代码,或者在标记符部分使用 SqlDataSource 控件来完成。无论采取哪种形式,该方法都让数据访问逻辑与表示层紧密结合。不过,建议将数据访问与表示层隔离开来。这个分离层被称作数据访问层 (DAL),通常作为一个单独的类库项目来实现。这种分层体系结构的优势得到了很好的论述,我们在该系列教程中也采用了此法。 有关基础数据源的所有代码,如创建到数据库的连接,发出SELECT, INSERT,UPDATE, and DELETE命令等,都应位于 DAL。表示层不应包含对这些数据访问代码的任何引用,而是通过调用 DAL 来实现所有的数据访问请求。数据访问层通常包含访问基础数据库数据的方法。例如,Northwind 数据库提供ProductsandCategories表,记录要销售的产品及其他们所属的类别。我们的 DAL 提供如下方法:
调用时,这些方法将连接到数据库,进行适当的查询,并返回查询结果。重要的是返回这些结果的方式。这些方法可以简单返回一个由数据库查询填充的 DataSet 或 DataReader,但理想的是应使用强类型的对象来返回这些结果。强类型对象指的是编译时对其 schema 进行严格定义的对象。相反,弱类型的对象指的是只有在运行时才知道其 schema 的对象。 例如,DataReader 和 DataSet(默认)是弱类型对象,因为它们的 schema 是由用来填充它们的数据库查询返回的列来定义的。要访问弱类型 DataTable 中的某列,需要使用如下语法:DataTable.Rows(index)("columnName"). 我们需要使用字符串或序号索引访问列名这一点就显示了该例中 DataTable 的弱类型特性。另一方面,强类型的 DataTable 有各自作为属性实现的列,生成如下代码:DataTable.Rows(index).columnName. 要返回强类型对象,开发人员可以创建他们自己的自定义业务对象或使用 Typed DataSet。一个业务对象由开发人员实现成一个类,该类的属性通常反映出该业务对象表示的基础数据库表的列。Typed DataSet 是由 Visual Studio 基于数据库 schema 为您生成的一个类,其成员都是强类型的。Typed DataSet 本身包括拓展了 ADO.NET DataSet、DataTable 和 DataRow 类的类。除强类型 DataTable 外,Typed DataSet 现在还包括 TableAdapter,该类具有填充 DataSet 的 DataTable 以及将 DataTable 中所作修改传回数据库的方法。 注意: 有关使用 Typed DataSet 与自定义业务对象的优劣比较的更多信息,请参见设计数据层组件并在层间传递数据。 我们对这些教程的体系结构使用强类型的 DataSet。图 3 说明了使用 Typed DataSet 的应用程序不同层间的工作流程。 图3: 选择添加一个新的 DataSet 到您的项目 创建一个 Typed DataSet 和 Table Adapter要创建我们的 DAL,要先将一个 Typed DataSet 添加到我们的项目。为此,右键单击 Solution Explorer 中的项目节点,并选择 Add a New Item。从模板列表中选择 DataSet 选项,并将其命名为Northwind.xsd。 图4: 选择添加一个新的 DataSet 到您的项目 单击 Add 后,出现提示添加 DataSet 到App_Code 文件夹,选择 Yes。接着出现 Typed DataSet 设计器并将启动 TableAdapter Configuration Wizard,允许您将您的第一个 TableAdapter 添加到 Typed DataSet。 Typed DataSet 充当一个强类型的数据集;它由强类型的 DataTable 实例组成,每个实例依次由强类型的 DataRow 实例组成。我们将为该教程系列所需的每个基础数据库表创建一个强类型的 DataTable。.我们开始为 Products 表创建 DataTable。 要记住,强类型的 DataTable 不包含有关如何从其基础数据库表访问数据的任何信息。为了检索数据以填充 DataTable,我们使用一个 TableAdapter 类,作为我们的数据访问层。对于我们的Products数据表,TableAdapter 将包含GetProducts(),GetProductByCategoryID(categoryID)等方法,我们将从表示层调用它们。DataTable 的作用是充当用来在层间传送数据的强类型对象。 TableAdapter Configuration Wizard 从提示您选择要操作的数据库开始。下拉列表显示出 Server Explorer 中的数据库。如果您没有把 Northwind 数据库添加到 Server Explorer,此时单击 New Connection 按钮进行该操作。 图5: 从下拉列表中选择 Northwind 数据库 选择了数据库并单击 Next 后, 将会问您是否希望在Web.config文件中保存连接字符串。保存了连接字符串,就避免了将连接字符串写在 TableAdapter 类的代码中。这样一旦以后连接字符串信息改变,要做的工作也变得简单。如果选择将连接字符串保存到放在<connectionStrings>区域的配置文件,以后可以通过 IIS GUI Admin Tool 内的新 ASP.NET 2.0 Property Page 选择加密以改进安全性或修改。这样更适合管理员工作。 图6: 保存连接字符串到Web.config 接下来,我们需要为第一个强类型的 DataTable 定义 schema,并为我们的 TableAdapter 提供填充强类型的 DataSet 时所用到的第一个方法。通过创建一个查询,可同时完成这两个步骤,这个查询能够返回我们希望映射我们的 DataTable 中的数据表的列。在向导结束时,我们将为该查询提供一个方法名称。完成后,就可以从我们的表示层调用该方法。此法将执行所定义的查询并填充强类型的 DataTable。 要开始定义 SQL 查询,就必须先说明希望 TableAdapter 进行查询的方式。我们可以使用一个 ad-hoc SQL 语句,创建一个新的存储过程,或使用现有的存储过程。对于本系列教程,我们将使用 ad-hoc SQL 语句。有关使用存储过程的例子,请参见Brian Noyes的文章: 使用 Visual Studio 2005 DataSet Designer 构建一个数据访问层。 图7: 使用 ad-hoc SQL 语句查询数据 此时,我们可以手动输入 SQL 查询。在 TableAdapter 创建第一个方法时,您通常希望查询返回需要在相应 DataTable 中存放的那些列。这可以通过创建返回来自Products表的所有列和行的查询实现: 图8: 在文本框输入 SQL 查询 也可以使用 Query Builder 用图像构建查询,如图 9 所示。 图9: 通过 Query Editor 用图像创建查询 创建查询之后,要在转到下一屏幕之前,单击 Advanced Options 按钮。在 Web Site 项目中,“Generate Insert, Update, and Delete statements”是默认选择的唯一高级选项;如果从 Class Library 或 Windows Project 运行该向导,“Use optimistic concurrency(使用优化并发)”选项将也被选中。现在暂不勾选该选项。我们将在以后的教程中详细介绍优化并发。 图10: 只选择“Generate Insert, Update, and Delete statements”选项 核实了高级选项后,单击 Next 进入最后一个屏幕。这时会询问我们选择那些方法添加到 TableAdapter。填充数据的模式有两种:
您可以在 TableAdapter 实现这两种模式中的一种或两种。也可以重命名此处所提供的方法。即使我们在整个教程中只使用第二种模式,我们也可以同时选中两个复选框。并且将更通用的GetData 法重命名为 GetProducts. 如果选中最后一个复选框 "GenerateDBDirectMethods",会为 TableAdapter 创建Insert(),Update(),和Delete()方法。如果没有选中该选项,所有的更新则需要通过 TableAdapter 唯一的Update()方法进行,该方法接受 Typed DataSet、DataTable、单个 DataRow 或 DataRow 数组。(如果没有选中图 9 高级选项中的"Generate Insert, Update, and Delete statements" 选项,该复选框的设置则不起作用。)在这里,我们勾选这个复选框。 图11: 将方法名称GetData 改为GetProducts 单击 Finish 结束向导。向导关闭后,返回到显示我们刚创建的 DataTable 的 DataSet 设计器。可以看到Products数据表中各列的列表 (ProductID,ProductName数据表中各列的列表),以及ProductsTableAdapter (Fill()的方法GetProducts())。 图12:Products DataTable 和ProductsTableAdapter已被添加到 Typed DataSet 这里,我们拥有一个带有单个 DataTable (Northwind.Products) 的Typed DataSet,还有一个提供GetProducts()方法的强类型 DataAdapter 类(NorthwindTableAdapters.ProductsTableAdapter) 。这些对象可用来通过类似以下代码访问所有产品的列表:
该代码不要求我们去编写任何针对数据访问的代码。我们不必生成任何 ADO.NET 类的实例,不必指定任何连接字符串、SQL 查询或存储过程。TableAdapter 会为我们提供底层的数据访问代码。 本示例中所使用的每个对象都是强类型的,允许 Visual Studio 提供 IntelliSense (智能感知)和编译时类型检查。而且,最好的是,TableAdapter 返回的 DataTable 可以绑定到 ASP.NET Web 数据控件,如 GridView、DetailsView、DropDownList、CheckBoxList 和其它。下面举例说明如何在 Page_Load事件处理程序仅用三行代码就将GetProducts() 方法返回的 DataTable 绑定到 GridView。 AllProducts.aspx
AllProducts.aspx.vb
图13: 显示在 GridView 中的产品列表 尽管本例还需要我们在 ASP.NET 页面的Page_Load事件处理程序中编写三行代码,不过在以后的教程中我们将详细介绍如何使用 ObjectDataSource,用声明的方式获取 DAL 数据。使用 ObjectDataSource 我们不必编写代码也可以进行分页和排序!
|