注释
此类 DataSet 和相关类是 2000 年代初的旧版 .NET Framework 技术,使应用程序能够在应用与数据库断开连接时处理内存中的数据。 这些技术对于使用户能够修改数据并将更改保留回数据库的应用特别有用。 尽管数据集是经过证实的成功技术,但新 .NET 应用程序的建议方法是使用 Entity Framework Core。 Entity Framework 提供了一种更自然的方式来将表格数据用作对象模型,并且具有更简单的编程接口。
“N 层”数据应用程序是指用于访问数据且分为多个逻辑层(或“多层”)的应用程序。 将应用程序组件分离为离散层可以提高应用程序的可维护性和可伸缩性。 该结构之所以具有这种优点,是因为它有利于采用可应用于单个层而无需重新设计整个解决方案的新技术。 N 层体系结构包括演示层、中间层和数据层。 中间层通常包括数据访问层、业务逻辑层和共享组件,例如身份验证和验证。 数据层包括关系数据库。 N 层应用程序通常将敏感信息存储在中间层的数据访问层中,以保持与访问呈现层的最终用户的隔离。 有关详细信息,请参阅 N 层数据应用程序概述。
将 n 层应用程序中的各个层分开的一种方法是为要包含在应用程序中的每个层创建离散项目。 类型化数据集包含一个 DataSet Project 属性,用于确定生成的数据集和 TableAdapter 代码应进入哪些项目。
本演练演示如何使用数据集设计器将数据集和TableAdapter代码分隔为离散类库项目。 在分隔数据集和 TableAdapter 代码后,在 Visual Studio 服务中创建 Windows Communication Foundation Services 和 WCF 数据服务 以调用数据访问层。 最后,将创建一个 Windows 窗体应用程序作为演示层。 此层从数据服务访问数据。
在本演练中,执行以下步骤:
创建包含多个项目的新 n 层解决方案。
将两个类库项目添加到 n 层解决方案。
使用 数据源配置向导创建类型化数据集。
将生成的 TableAdapters 和数据集代码分离到离散项目中。
创建 Windows Communication Foundation (WCF) 服务以调用数据访问层。
在服务中创建函数以从数据访问层检索数据。
创建一个 Windows 窗体应用程序,用作演示层。
创建绑定到数据源的 Windows 窗体控件。
编写代码以填充数据表。
先决条件
若要完成本教程,需要 .NET 桌面开发和数据存储以及处理 Visual Studio 中安装的工作负载。 若要安装它们,请打开 Visual Studio 安装程序,然后选择要修改的 Visual Studio 版本旁边的 修改(或 更多>修改)。 请参阅修改 Visual Studio。
本演练使用 SQL Server Express LocalDB 和 Northwind 示例数据库。
如果没有 SQL Server Express LocalDB,请从 SQL Server Express 下载页或通过 Visual Studio 安装程序安装它。 在 Visual Studio 安装程序中,可以将 SQL Server Express LocalDB 作为 .NET 桌面开发 工作负载的一部分或作为单个组件安装。
按照以下步骤安装 Northwind 示例数据库:
在 Visual Studio 中,打开 SQL Server 对象资源管理器 窗口。 (SQL Server 对象资源管理器作为数据存储和处理工作负荷的一部分安装在 Visual Studio 安装程序中。)展开“SQL Server”节点。 右键单击 LocalDB 实例并选择“新建查询”。
此时会打开查询编辑器窗口。
将 Northwind Transact-SQL 脚本 复制到剪贴板。 此 T-SQL 脚本从头开始创建 Northwind 数据库,并使用数据填充该数据库。
将 T-SQL 脚本粘贴到查询编辑器中,然后选择 “执行” 按钮。
短时间后,查询将完成运行并创建 Northwind 数据库。
在 Visual Studio 中,打开 SQL Server 对象资源管理器 窗口。 (SQL Server 对象资源管理器作为数据存储和处理工作负荷的一部分安装在 Visual Studio 安装程序中。)展开“SQL Server”节点。 右键单击 LocalDB 实例并选择“新建查询”。
如果未看到 LocalDB 实例,请使用工具栏按钮 添加 SQL Server。 此时会显示该对话框。 在对话框中,展开 “本地 ”,然后选择 “MSSQLLocalDB”。 输入相应的凭据。 可以保留数据库的默认选项。

选择连接。 在 SQL Server 对象资源管理器中为 LocalDB 添加节点。
右键单击 LocalDB 实例并选择“新建查询”。
此时会打开查询编辑器窗口。
将 Northwind Transact-SQL 脚本 复制到剪贴板。 此 T-SQL 脚本从头开始创建 Northwind 数据库,并使用数据填充该数据库。
将 T-SQL 脚本粘贴到查询编辑器中,然后选择 “执行” 按钮。
短时间后,查询将完成运行并创建 Northwind 数据库。
创建 n 层解决方案和类库以保存数据集(DataEntityTier)
本演练的第一步是创建解决方案和两个类库项目。 第一个类库包含数据集(生成的类型化的DataSet类和包含应用程序数据的DataTables)。 此项目用作应用程序的数据实体层,通常位于中间层。 数据集创建初始数据集,并将代码自动分隔到两个类库中。
注释
单击“ 确定”之前,请务必正确命名项目和解决方案。 这样做将使你更轻松地完成本演练。
创建 n 层解决方案和 DataEntityTier 类库
在 Visual Studio 中,使用适用于 C# 或 Visual Basic 的 Windows 窗体应用(.NET Framework) 项目模板创建项目。 不支持 .NET Core、.NET 5 及更高版本。
将项目命名 为 DataEntityTier。
将解决方案命名为 NTierWalkthrough,然后选择 “确定”。
将创建包含 DataEntityTier 项目的 NTierWalkthrough 解决方案并将其添加到 解决方案资源管理器。
创建用于保存 TableAdapter 的类库 (DataAccessTier)
创建 DataEntityTier 项目后,下一步是创建另一个类库项目。 此项目将保存生成的 TableAdapter,它称为应用程序的“数据访问层”。 数据访问层包含连接到数据库所需的信息,通常位于中间层中。
为 TableAdapters 创建单独的类库
右键单击 解决方案资源管理器 中的解决方案,然后选择“ 添加新>项目”。
选择 类库(.NET Framework) 项目模板。
将项目命名 为 DataAccessTier ,然后选择 “确定”。
DataAccessTier 项目即被创建并添加到 NTierWalkthrough 解决方案中。
创建数据集
下一步是创建类型化数据集。 使用数据集类(包括 DataTables 类)和单个项目中的 TableAdapter 类创建类型化数据集。 所有类都生成到一个单独的文件中。当您将数据集和 TableAdapters 分离到不同的项目中时,数据集类会被移动到另一个项目中,而TableAdapter类则保留在原始项目中。 因此,应在最终包含 TableAdapter 的项目(DataAccessTier 项目)中创建数据集。 使用 数据源配置向导创建数据集。
注释
必须有权访问 Northwind 示例数据库才能创建连接。 有关如何设置 Northwind 示例数据库的信息,请参阅 如何:安装示例数据库。
创建数据集
在解决方案资源管理器中选择 DataAccessTier。
在 “数据 ”菜单上,选择“ 显示数据源”。
此时会打开 “数据源 ”窗口。
在 “数据源 ”窗口中,选择“ 添加新数据源 ”以启动 数据源配置向导。
在“ 选择数据源类型 ”页上,选择“ 数据库 ”,然后选择“ 下一步”。
在 “选择数据连接 ”页上,执行以下作之一:
如果下拉列表中提供了与 Northwind 示例数据库的数据连接,请选择它。
或
选择 “新建连接 ”以打开“ 添加连接 ”对话框。
如果数据库需要密码,请选择包含敏感数据的选项,然后选择“ 下一步”。
注释
如果选择了本地数据库文件(而不是连接到 SQL Server),系统可能会询问是否要将该文件添加到项目。 选择 “是 ”将数据库文件添加到项目。
在“将连接字符串保存到应用程序配置文件”页上选择“下一步”。
在 “选择数据库对象” 页面上展开 “表” 节点。
选中 “客户 ”和 “订单 ”表的复选框,然后选择“ 完成”。
NorthwindDataSet 将添加到 DataAccessTier 项目,并显示在 “数据源 ”窗口中。
将 TableAdapters 与数据集分开
创建数据集后,将生成的数据集类与 TableAdapters 分开。 为此,请将 DataSet Project 属性设置为存储分隔的数据集类的项目的名称。
将 TableAdapters 与数据集进行分离
双击解决方案资源管理器中的 NorthwindDataSet.xsd,在数据集设计器中打开数据集。
在设计器上选择一个空区域。
在“属性”窗口中找到“数据集项目”节点。
在 “数据集项目” 列表中,选择 “DataEntityTier”。
在“生成”菜单上,选择“生成解决方案”。
数据集和 TableAdapters 被分为两个类库项目。 最初包含整个数据集的项目(
DataAccessTier)现在仅包含 TableAdapters。 DataSet Project 属性DataEntityTier中指定的项目包含类型化数据集:NorthwindDataSet.Dataset.Designer.vb(或NorthwindDataSet.Dataset.Designer.cs)。
注释
在分隔数据集和 TableAdapters(通过设置 DataSet Project 属性)时,项目中的现有分部数据集类将不会自动移动。 现有数据集分部类必须手动移动到数据集项目。
创建新的服务应用程序
本演练演示如何使用 WCF 服务访问数据访问层,因此让我们创建新的 WCF 服务应用程序。
创建新的 WCF 服务应用程序
右键单击 解决方案资源管理器 中的解决方案,然后选择“ 添加新>项目”。
在“ 新建项目 ”对话框中的左侧窗格中,选择 WCF。 在中间窗格中,选择 WCF 服务库。
将项目命名 为 DataService ,然后选择“ 确定”。
DataService 项目已创建并添加到 NTierWalkthrough 解决方案。
在数据访问层中创建方法以返回客户和订购数据
数据服务必须调用数据访问层中的两种方法: GetCustomers 和 GetOrders。 这些方法返回 Northwind Customers 和 Orders 表。 在DataAccessTier项目中创建GetCustomers方法和GetOrders方法。
创建一个在数据访问层中返回 Customers 表的方法
在 解决方案资源管理器中,双击 NorthwindDataset.xsd 打开数据集。
右键单击 CustomersTableAdapter ,然后单击“ 添加查询”。
在 “选择命令类型 ”页上,保留 “使用 SQL 语句 ”的默认值,然后单击“ 下一步”。
在 “选择查询类型 ”页上,保留 返回行的 SELECT 的默认值,然后单击“ 下一步”。
在 “指定 SQL SELECT 语句 ”页上,保留默认查询,然后单击“ 下一步”。
在“选择要生成的方法”页上,在“返回 DataTable”部分中,为“方法名称”键入GetCustomers。
单击“完成”。
在数据访问层中创建一个返回订单表的方法
右键单击 OrdersTableAdapter ,然后单击“ 添加查询”。
在 “选择命令类型 ”页上,保留 “使用 SQL 语句 ”的默认值,然后单击“ 下一步”。
在 “选择查询类型 ”页上,保留 返回行的 SELECT 的默认值,然后单击“ 下一步”。
在 “指定 SQL SELECT 语句 ”页上,保留默认查询,然后单击“ 下一步”。
在“选择要生成的方法”页上,在“返回 DataTable”部分为方法名称键入GetOrders。
单击“完成”。
在 “生成” 菜单上,单击 “生成解决方案” 。
向数据服务添加对数据实体和数据访问级别的引用
由于数据服务需要来自数据集和 TableAdapters 的信息,因此请添加对 DataEntityTier 和 DataAccessTier 项目的引用。
添加对数据服务的引用
在解决方案资源管理器中右键单击 DataService,然后单击“添加引用”。
单击“添加引用”对话框中的“项目”选项卡。
同时选择 DataAccessTier 和 DataEntityTier 项目。
单击 “确定” 。
向服务添加函数以调用数据访问层中的 GetCustomers 和 GetOrders 方法
现在,数据访问层包含返回数据的方法,请在数据服务中创建方法以调用数据访问层中的方法。
注释
对于 C# 项目,必须添加对 System.Data.DataSetExtensions 程序集的引用,以编译以下代码。
在数据服务中创建 GetCustomers 和 GetOrders 函数
在 DataService 项目中,双击 IService1.vb 或 IService1.cs。
在“在此处添加服务操作”注释的下方添加以下代码:
[OperationContract] DataEntityTier.NorthwindDataSet.CustomersDataTable GetCustomers(); [OperationContract] DataEntityTier.NorthwindDataSet.OrdersDataTable GetOrders();注释
本教程的代码在 C# 和 Visual Basic 中提供。 若要在此页面上在 C# 和 Visual Basic 之间切换代码语言,请使用右侧页面顶部的代码语言切换器。
在 DataService 项目中,双击 Service1.vb (或 Service1.cs)。
将以下代码添加到 Service1 类:
public DataEntityTier.NorthwindDataSet.CustomersDataTable GetCustomers() { DataAccessTier.NorthwindDataSetTableAdapters.CustomersTableAdapter CustomersTableAdapter1 = new DataAccessTier.NorthwindDataSetTableAdapters.CustomersTableAdapter(); return CustomersTableAdapter1.GetCustomers(); } public DataEntityTier.NorthwindDataSet.OrdersDataTable GetOrders() { DataAccessTier.NorthwindDataSetTableAdapters.OrdersTableAdapter OrdersTableAdapter1 = new DataAccessTier.NorthwindDataSetTableAdapters.OrdersTableAdapter(); return OrdersTableAdapter1.GetOrders(); }在 “生成” 菜单上,单击 “生成解决方案” 。
创建表示层以显示数据服务中的数据
现在,该解决方案包含具有方法的数据服务(该方法调用数据访问层),请创建另一个项目来调用数据服务并将数据呈现给用户。 对于本演练,创建一个 Windows 窗体应用程序;它将充当 N 层应用程序的表示层。
创建表示层项目
右键单击 解决方案资源管理器 中的解决方案,然后选择“ 添加新>项目”。
在“ 新建项目 ”对话框中的左侧窗格中,选择 “Windows 桌面”。 在中间窗格,选择“Windows 窗体应用”。
将项目命名为 PresentationTier ,然后单击“ 确定”。
PresentationTier 项目已创建,并已添加到该 NTierWalkthrough 解决方案。
将 PresentationTier 项目设置为启动项目
我们将 PresentationTier 项目设置为解决方案的启动项目,因为它是呈现数据并与之交互的实际客户端应用程序。
将新的表示层项目设置为启动项目
- 在 解决方案资源管理器中,右键单击 PresentationTier ,然后单击“ 设置为启动项目”。
添加对表示层的引用
客户端应用程序 PresentationTier 需要对数据服务的服务引用才能访问服务中的方法。 此外,需要对数据集的引用才能启用 WCF 服务的类型共享。 在通过数据服务启用类型共享之前,添加到分部数据集类的代码不适用于呈现层。 由于通常将代码(如验证代码)添加到数据表的行和列更改事件,因此可能需要从客户端访问此代码。
添加定义表示层的引用
在 解决方案资源管理器中,右键单击 PresentationTier 并选择 “添加引用”。
在“ 添加引用 ”对话框中,选择“ 项目 ”选项卡。
选择 DataEntityTier ,然后选择 “确定”。
添加对表示层的服务引用
在 解决方案资源管理器中,右键单击 PresentationTier 并选择 “添加服务引用”。
在“ 添加服务引用 ”对话框中,选择“ 发现”。
选择 Service1 ,然后选择 “确定”。
注释
如果当前计算机上有多个服务,请选择之前在本演练中创建的服务(包含
GetCustomers和GetOrders方法的服务)。
将 DataGridViews 添加到窗体以显示数据服务返回的数据
向数据服务添加服务引用后, “数据源 ”窗口会自动填充服务返回的数据。
向窗体添加两个数据绑定的数据网格视图
在 解决方案资源管理器中,选择 PresentationTier 项目。
在 “数据源 ”窗口中,展开 NorthwindDataSet 并找到 “客户” 节点。
将 “客户 ”节点拖到 Form1 上。
在“数据源”窗口中,展开“客户”节点并找到相关的“订单”节点(嵌套在“客户”节点中的“订单”节点)。
将相关的 “订单” 节点拖到 Form1 上。
通过双击窗体的空白区域,创建一个
Form1_Load事件处理程序。将以下代码添加到
Form1_Load事件处理程序。
增加服务允许的最大消息大小
默认值 maxReceivedMessageSize 不够大,无法保存从 Customers 表 Orders 检索到的数据。 在以下步骤中,将值增加到 6553600。 您在客户端上更改值后,服务引用会自动更新。
注释
较低的默认大小旨在限制拒绝服务(DoS)攻击的风险。 有关详细信息,请参阅 MaxReceivedMessageSize。
提高“maxReceivedMessageSize”值
在解决方案资源管理器中,双击 PresentationTier 项目中的app.config 文件。
找到 maxReceivedMessageSize 属性并将值更改为
6553600。 如果未看到条目basicHttpBinding,请添加如下示例所示的条目:<system.serviceModel> <bindings> <basicHttpBinding> <binding maxBufferSize="6553600" maxReceivedMessageSize="6553600" /> </basicHttpBinding> </bindings> </system.serviceModel>
测试应用程序
按 F5 运行应用程序。 从数据服务中检索 Customers 表和 Orders 表的数据,并在窗体上显示。
后续步骤
根据应用程序要求,在基于 Windows 的应用程序中保存相关数据后,可能需要执行几个步骤。 例如,可以对此应用程序进行以下增强:
将验证添加到数据集。
向服务添加其他方法,以便将数据更新回数据库。