从 DataAdapter 填充 DataSet

适用于: .NET Framework .NET .NET Standard

下载 ADO.NET

ADO.NET DataSet 是数据常驻内存的表示形式,可提供与数据源无关的一致关系编程模型。 DataSet 表示整个数据集,其中包含表、约束和表之间的关系。 由于 DataSet 独立于数据源,因此 DataSet 可以包含应用程序本地的数据,也可以包含来自多个数据源的数据。 与现有数据源的交互通过 DataAdapter来控制。

SelectCommandDataAdapter 属性是一个 Command 对象,用于从数据源中检索数据。 InsertCommandUpdateCommandDeleteCommandDataAdapter 属性是 Command 对象,用于按照对 DataSet中数据的修改来管理对数据源中数据的更新。 通过 DataAdapter 更新数据源中更详细地介绍了这些属性。

FillDataAdapter 方法用于使用 DataSetSelectCommand 结果填充 DataAdapterFill 将要填充的 DataSet 、和 DataTable 对象(或要使用从 DataTable 中返回的行来填充的 SelectCommand的名称)作为它的参数。

备注

使用 DataAdapter 检索表的全部内容会花费些时间,尤其是在表中有很多行时。 这是因为访问数据库,定位和处理数据,然后将数据传输到客户端是需要很长时间的。 将表中全部内容提取到客户端还会在服务器上锁定所有行。 若要提高性能,您可以使用 WHERE 子句使返回客户端的行数大为减少。 还可以通过只显式列出 SELECT 语句要求的列减少返回到客户端的数据量。 另一种好的变通方法是以批次检索行(例如一次检索几百行),并且在客户端完成当前批次后只检索下一批次。

Fill 方法使用 DataReader 对象来隐式地返回用于在 DataSet中创建表的列名称和类型,以及用于填充 DataSet中的表行的数据。 表和列仅在不存在时才创建;否则, Fill 将使用现有的 DataSet 架构。 列类型根据 ADO.NET 中的数据类型映射中的表创建为 .NET Framework 类型。 除非数据源中存在主键且 DataAdapter.MissingSchemaAction 设置为 MissingSchemaAction.AddWithKey,否则不会创建主键。 如果 Fill 发现某个表存在主键,对于主键列的值与从数据源返回的行的主键列的值匹配的行,将使用数据源中的数据重写 DataSet 中的数据。 如果未找到任何主键,则将数据追加到 DataSet中的表。 Fill 使用填充 DataSet 时可能存在的任何映射(请参阅 DataAdapter、DataTable 和 DataColumn 映射)。

备注

如果 SelectCommand 返回 OUTER JOIN 的结果,则 DataAdapter 不会为生成的 PrimaryKey 设置 DataTable值。 您必须自己定义 PrimaryKey 以确保正确解析重复行。

以下代码示例创建了一个 SqlDataAdapter 实例,使用 Microsoft SQL Server SqlConnection 数据库的 Northwind 并使用客户列表填充 DataTable 中的 DataSet 。 向 SqlConnection 构造函数传递的 SQL 语句和 SqlDataAdapter 参数用于创建 SelectCommandSqlDataAdapter属性。

示例

// Assumes that connection is a valid SqlConnection object.
string queryString =
"SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");

注意

此示例中所示的代码不显式打开和关闭 Connection。 如果 Fill 方法发现连接尚未打开,它将隐式地打开 Connection 正在使用的 DataAdapter 。 如果 Fill 已打开连接,则它还将在 Fill 完成时关闭连接。 当处理单一操作(如 FillUpdate)时,这可以简化您的代码。 但是,如果您在执行多项需要打开连接的操作,则可以通过以下方式提高应用程序的性能:显式调用 OpenConnection方法,对数据源执行操作,然后调用 CloseConnection方法。 应尝试使数据源的连接打开的时间尽可能短,以便释放资源供其他客户端应用程序使用。

多个结果集

如果 DataAdapter 遇到多个结果集,则将在 DataSet中创建多个表。 这些表的命名方式为默认名称 Table 加上N,N 从 0 开始递增,如以 Table0 为第一个表名,依次类推。 如果以参数形式向 Fill 方法传递表名,则这些表的命名方式为默认名称 TableName 加上N,N 从 0 开始递增,如以 TableName0 为第一个表名,依次类推。

从多个 DataAdapter 填充 DataSet

一个 DataSet 可以与任意数量的 DataAdapter 对象一起使用。 每个 DataAdapter 都可用于填充一个或多个 DataTable 对象并将更新解析回相关数据源。 DataRelationConstraint 对象可以在本地添加到 DataSet ,这样您就可以关联来自不同数据源的数据。 例如,DataSet 可以包含来自 Microsoft SQL Server 数据库、通过 OLE DB 公开的 IBM DB2 数据库以及对 XML 进行流处理的数据源的数据。 一个或多个 DataAdapter 对象可以处理与每个数据源的通信。

示例

以下代码示例从 Microsoft SQL Server 上的 Northwind 数据库填充客户列表,从存储在 Microsoft Access 上的 Northwind 数据库填充订单列表。 已填充的表通过 DataRelation相关联,这样,客户列表将与相应客户的订单一起显示出来。

// Assumes that customerConnection and orderConnection are valid SqlConnection objects.
SqlDataAdapter custAdapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", customerConnection);
SqlDataAdapter ordAdapter = new SqlDataAdapter(
"SELECT * FROM Orders", orderConnection);

DataSet customerOrders = new DataSet();

custAdapter.Fill(customerOrders, "Customers");
ordAdapter.Fill(customerOrders, "Orders");

DataRelation relation = customerOrders.Relations.Add("CustOrders",
customerOrders.Tables["Customers"].Columns["CustomerID"],
customerOrders.Tables["Orders"].Columns["CustomerID"]);

foreach (DataRow pRow in customerOrders.Tables["Customers"].Rows)
{
    Console.WriteLine(pRow["CustomerID"]);
    foreach (DataRow cRow in pRow.GetChildRows(relation))
        Console.WriteLine("\t" + cRow["OrderID"]);
}

SQL Server Decimal 类型

默认情况下,DataSet 使用 .NET 数据类型存储数据。 对于大多数应用程序,这些类型都提供了一种方便的数据源信息表示形式。 但是,当数据源中的数据类型是 SQL Server decimal 或 numeric 数据类型时,这种表示形式可能会导致问题。 .NET decimal 数据类型最多允许 28 个有效数字,而 SQL Server decimal 数据类型则允许 38 个有效数字。 如果 SqlDataAdapterFill 操作过程中确定 SQL Server decimal 字段的精度大于 28 个字符,则不会将当前行添加到 DataTable。 此时将发生 FillError 事件,使您能够确定是否将发生精度损失并作出适当的响应。 有关 FillError 事件的详细信息,请参阅处理 DataAdapter 事件。 若要获取 SQL Server decimal 值,还可以使用 SqlDataReader 对象并调用 GetSqlDecimal 方法。

ADO.NET 还增强了对 DataSet 中的 System.Data.SqlTypes 的支持。 有关详细信息,请参阅 SqlTypes and the DataSet

另请参阅