使用英语阅读

通过


在 .NET Framework 应用程序中使用 TableAdapters 填充数据集

备注

数据集和相关类是 2000 年代初的旧 .NET Framework 技术,使应用程序能够在应用程序与数据库断开连接时处理内存中的数据。 这些技术对于使用户能够修改数据并将更改保留回数据库的应用程序特别有用。 尽管数据集被证明是非常成功的技术,但我们建议新的 .NET 应用程序使用 Entity Framework Core。 Entity Framework 提供了一种更自然的方式来将表格数据用作对象模型,并且具有更简单的编程接口。

TableAdapter 组件根据指定的一个或多个查询或存储过程,使用数据库中的数据填充数据集。 TableAdapters 还可以对数据库执行添加、更新和删除作,以保留对数据集所做的更改。 此外,还可以发出与任何特定表无关的全局命令。

备注

Visual Studio 设计器会生成 TableAdapter。 如果要以编程方式创建数据集,请使用 DataAdapter .NET 类。

有关 TableAdapter 操作的详细信息,您可以直接跳到以下某篇文章:

文章 描述
创建和配置 Tableadapter 了解如何使用设计器创建和配置 TableAdapters。
创建参数化 TableAdapter 查询 了解如何让用户向 TableAdapter 过程或查询提供参数。
使用 TableAdapter 直接访问数据库 了解如何使用 TableAdapters 的 DbDirect 方法。
在填充数据集 时关闭约束 了解如何在更新数据时使用外键约束。
扩展 TableAdapter 的功能 了解如何将自定义代码添加到 TableAdapters。
将 XML 数据读入数据集 了解如何在数据集中使用 XML 数据。

TableAdapter 概述

TableAdapters 是设计器生成的组件,用于连接到数据库、运行查询或存储过程,并使用返回的数据填充其 DataTable。 TableAdapters 还会将更新的数据从应用程序发送回数据库。 只要它返回符合其关联表架构的数据,就可以对 TableAdapter 运行任意数量的查询。 下图显示了 TableAdapters 如何与内存中的数据库和其他对象进行交互:

显示客户端应用程序中的 TableAdapter 数据流的图。

虽然 TableAdapter 是使用数据集设计器设计的,但 TableAdapter 类并不作为 DataSet 的嵌套类生成。 相反,它们位于特定于每个数据集的单独命名空间中。 例如,如果你有一个名为 NorthwindDataSet的数据集,则与 NorthwindDataSet 中的 DataTable 对象关联的 TableAdapters 位于 NorthwindDataSetTableAdapters 命名空间中。 若要以编程方式访问特定的 TableAdapter,请声明 TableAdapter 类的新实例。 例如:

NorthwindDataSet northwindDataSet = new NorthwindDataSet();

NorthwindDataSetTableAdapters.CustomersTableAdapter customersTableAdapter = 
    new NorthwindDataSetTableAdapters.CustomersTableAdapter();

customersTableAdapter.Fill(northwindDataSet.Customers);

关联的 DataTable 架构

创建 TableAdapter 时,可以使用初始查询或存储过程来定义 TableAdapter 关联 DataTable的架构。 通过调用 TableAdapter 的 Fill 方法来运行此初始查询或存储过程,方法会将数据填充到 TableAdapter 关联的 DataTable中。 对 TableAdapter 主查询所做的任何更改都反映在关联数据表的架构中。 例如,如果从主查询中删除列,数据集设计器还会从关联的数据表中删除该列。 如果 TableAdapter 上的任何其他查询使用返回不在主查询中的列的 SQL 语句,数据集设计器将尝试同步主查询和附加查询之间的列更改。

TableAdapter 更新命令

TableAdapter 的更新功能取决于 TableAdapter 向导主查询中可用的信息量。 例如,配置为从多个表(使用 JOIN)、标量值、视图或聚合函数结果中提取值的 TableAdapters,最初是不具备将更新发送回基础数据库能力的。 但是,可以在 属性 窗口中手动配置 InsertCommandUpdateCommand以及 DeleteCommand 属性。

TableAdapter 查询

TableAdapters 可以包含多个查询来填充其关联的数据表。 只要每个查询返回符合其关联数据表的架构的数据,您可以根据应用程序的要求为 TableAdapter 定义任意数量的查询。 此功能使 TableAdapter 能够基于不同的条件加载不同的结果。

显示具有多个查询的 TableAdapter 的 此图显示具有多个查询的 TableAdapter。

例如,如果应用程序包含具有客户名称的表,则可以创建一个查询,该查询使用以特定字母开头的每个客户名称填充该表。 可以创建另一个查询,将所有位于相同州的客户填充到表中。 若要使用位于特定州的客户填充 Customers 表,请创建一个 FillByState 查询,将一个参数用作州值,如下所示:SELECT * FROM Customers WHERE State = @State。 通过调用 FillByState 方法并传入参数值来运行查询,例如:CustomerTableAdapter.FillByState("WA")

除了添加返回与 TableAdapter 数据表相同的架构数据的查询外,还可以添加返回标量值(单个)值的查询。 例如,返回客户计数(SELECT Count(*) From Customers)的查询对 CustomersTableAdapter有效,即使返回的数据不符合表的架构。

ClearBeforeFill 属性

默认情况下,每次运行查询以填充 TableAdapter 的数据表时,将清除现有数据,并且只会将查询的结果加载到表中。 如果要添加或合并查询返回到数据表中现有数据的数据,请将 TableAdapter 的 ClearBeforeFill 属性设置为 false。 无论是否清除数据,如果想要保留更新,则必须显式将更新发送回数据库。 因此,在运行填充表的另一个查询之前,请确保保存对表中数据所做的任何更改。 有关详细信息,请参阅使用 TableAdapter 更新数据

TableAdapter 继承

TableAdapters 通过封装配置的 DataAdapter 类来扩展标准数据适配器的功能。 默认情况下,TableAdapter 继承自 Component 类,不能强制转换为 DataAdapter 类。 将 TableAdapter 强制转换为 DataAdapter 类会导致 InvalidCastException 错误。 若要更改 TableAdapter 的基类,请指定一个类,该类派生自数据集设计器中 TableAdapter 的 基类 属性中的 Component 类。

TableAdapter 方法和属性

TableAdapter 类不是 .NET 类型,这意味着无法在对象浏览器或参考文档中查找它。 当您使用前面所述的某个向导时,Visual Studio 会在设计时创建它。 Visual Studio 分配给创建的 TableAdapter 的名称基于正在使用的表的名称。 例如,当基于名为 Orders的数据库中的表创建 TableAdapter 时,TableAdapter 将命名为 OrdersTableAdapter。 若要更改 TableAdapter 的类名,请使用数据集设计器 属性 窗口中的 Name 属性。

TableAdapter 的常用方法和属性如下所示:

成员 描述
TableAdapter.Fill 利用 TableAdapter 的 SELECT 命令结果来填充其关联的数据表。
TableAdapter.Update 将更改发送回数据库,并返回一个整数,表示受更新影响的行数。 有关详细信息,请参阅使用 TableAdapter 更新数据
TableAdapter.GetData 返回一个填充有数据的新 DataTable
TableAdapter.Insert 在数据表中创建一个新行。 有关详细信息,请参阅 将新记录插入数据库
TableAdapter.ClearBeforeFill 确定在调用其中一个 Fill 方法之前是否清空数据表。

TableAdapter 更新方法

TableAdapters 使用数据命令从数据库读取和写入数据。 使用 TableAdapter 的初始 Fill(main)查询作为创建关联数据表的架构的基础,以及与 TableAdapter.Update 方法关联的 InsertCommandUpdateCommandDeleteCommand 命令。 调用 TableAdapter 的 Update 方法时,它将运行最初配置 TableAdapter 时创建的语句,而不是使用 TableAdapter 查询配置向导添加的额外查询之一

使用 TableAdapter 时,它可以有效地执行与您通常使用的命令相同的操作。 例如,调用适配器的 Fill 方法时,适配器在其 SelectCommand 属性中运行数据命令,并使用数据读取器(例如,SqlDataReader)将结果集加载到数据表中。 同样,调用适配器的 Update 方法时,它会针对数据表中每个已更改记录运行相应的命令(在 UpdateCommandInsertCommandDeleteCommand 属性中)。

备注

如果主查询包含足够的信息,设计器会在设计器生成 TableAdapter 时默认创建 InsertCommandUpdateCommandDeleteCommand 命令。 但是,如果 TableAdapter 的主查询不仅仅是单个表 SELECT 语句,设计器可能无法生成这些命令。 在这种情况下,运行 TableAdapter.Update 方法时可能会收到错误。

TableAdapter GenerateDbDirectMethods

除了 InsertCommandUpdateCommandDeleteCommand之外,还可以使用以下方法创建 TableAdapters,这些方法可以直接针对数据库运行:TableAdapter.InsertTableAdapter.UpdateTableAdapter.Delete。 你可以直接调用这些方法来操作数据库中的数据。 这样做意味着你可从代码中调用这些单独的方法,而不是调用 TableAdapter.Update 来处理对关联数据表挂起的插入、更新和删除操作。

如果不想创建这些直接方法,请在 属性 窗口中将 TableAdapter 的 GenerateDbDirectMethods 属性设置为 False。 添加到 TableAdapter 的额外查询是独立查询,不会生成这些方法。

TableAdapter 支持可以为 null 的类型

TableAdapters 支持可为 null 的类型 Nullable<T>T?。 有关 Visual Basic 中可为 null 的类型的详细信息,请参阅 可以为 Null 的值类型(Visual Basic)。 有关 C# 中可空类型的更多信息,请参阅 可空值类型(C#)

TableAdapterManager 引用

默认情况下,在创建包含相关表的数据集时,Visual Studio 会生成 TableAdapterManager 类。 若要防止生成类,请将数据集 Hierarchical Update 属性的值更改为 false。 将具有关系的表拖到 Windows 窗体或 WPF 页面的设计图面上时,Visual Studio 将声明类的成员变量。 如果不使用数据绑定,则必须手动声明变量。

由于 TableAdapterManager 类不是 .NET 类型,因此它不会出现在参考文档中。 Visual Studio 在设计时创建它作为数据集创建过程的一部分。

下表列出了 TableAdapterManager 类的常用方法和属性:

成员 描述
UpdateAll 方法 保存所有数据表中的所有数据。
BackUpDataSetBeforeUpdate 属性 确定在执行 TableAdapterManager.UpdateAllmethod.Boolean之前是否创建数据集的备份副本。
tableNameTableAdapter 属性 表示 TableAdapter。 生成的 TableAdapterManager 包含其管理的每个 TableAdapter 的属性。 例如,具有 Customers 和 Orders 表的数据集将生成包含 CustomersTableAdapterOrdersTableAdapter 属性的 TableAdapterManager。
UpdateOrder 属性 控制单个插入、更新和删除命令的顺序。 将此属性设置为 TableAdapterManager.UpdateOrderOption 枚举中的值之一。

默认情况下,UpdateOrder 设置为 InsertUpdateDelete,这意味着对数据集中的所有表执行插入、更新和删除作。

安全

当您使用设置为 TextCommandType 属性的数据命令时,请仔细检查从客户端发送的信息,然后再将其传递给数据库。 恶意用户可能会尝试发送修改后的 SQL 语句或额外的 SQL 语句,以获取对数据库的未经授权的访问。 将用户输入传输到数据库之前,请始终验证信息是否有效。 最佳做法是尽可能使用参数化查询或存储过程。