C# DataAdapter 使用指南:填充、更新与事件详解

许南星
许南星
发布时间:2026-10-15| 5人浏览过
原创

本文详细介绍 C# 中 DataAdapter(以 SqlDataAdapter 为例)的使用方式,涵盖数据填充的多种策略(包括多结果集处理和分页)、基于 DataTable 映射的数据更新机制、SqlCommandBuilder 的自动命令生成以及行级更新事件的捕获。

一、填充数据(Fill)

DataAdapter 主要通过 Fill 方法将数据源中的结果集加载到 DataSet 中。在执行过程中,如果连接未打开,它会自动打开并在完成后关闭;若连接已打开,则需要手动管理其状态。

第1步:基础填充与表映射

目的:将查询结果加载到 DataSet 并根据需要重命名内存中的表名和列名。

代码示例:

DataSet ds = new DataSet();
// 查询包含两个结果集的 SQL
SqlCommand cmd = new SqlCommand("select * from Catogories;select * from Customers", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);

// 配置表映射:第一个参数是数据源返回的第一个表的默认名称(Table),第二个参数是 DataSet 中创建的表名
DataTableMapping map = da.TableMappings.Add("Table", "Customer");
map.ColumnMappings.Add("Name", "CustomerName"); // 列重映射

// 处理模式冲突:AddWithKey 会添加主键信息
da.MissingSchemaAction = MissingSchemaAction.AddWithKey;

// 填充数据:新增的 DataTable 默认为 "Table",后续为 "Table1" 等
da.Fill(ds); 
da.Fill(ds, "Customer"); // 显式指定目标表名

// 分页填充:从索引0开始,取10000行
da.Fill(ds, 0, 10000, "Customer");

// 仅填充架构信息(列结构),不加载数据
da.FillSchema(ds, System.Data.SchemaType.Source, "Customer");

第2步:处理多条 SQL 语句的结果集

当 SQL 命令包含分号分隔的多条语句时,DataAdapter 会为每个结果集创建一个新的 DataTable。以下是三种常见的处理方式:

方案1:使用不同的 CommandText 分别填充

每次填充前修改 Command 文本,或使用不同的 DataAdapter 实例。需注意区分传入的表名字符串。

SqlCommand cmd = new SqlCommand("select * from Catogories", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds, "Catogories");

cmd.CommandText = "select * from Customers";
SqlDataAdapter da2 = new SqlDataAdapter(cmd);
da2.Fill(ds, "Customer");

方案2:复用 DataAdapter 更改 Text

通过修改同一个 DataAdapter 的 SelectCommand.CommandText 属性来依次填充不同数据。

SqlCommand cmd = new SqlCommand("select * from Catogories", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds, "Catogories");

da.SelectCommand.CommandText = "select * from Customers";
da.Fill(ds, "Customer");

方案3:一次性获取多结果集(推荐)

在一条 SQL 中使用分号,DataAdapter 会自动按顺序将结果集填入 DataSet 的不同表中(表名默认为 Table, Table1 等,可通过 TableMappings 定制)。

SqlCommand cmd = new SqlCommand("select * from Catogories;select * from Customers", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);

二、更新数据(Update)

当内存中的 DataSet 发生改变后,可以通过 Update 方法将这些变更同步回数据库。通常需要配合 SqlCommandBuilder 自动生成更新指令。

第3步:增量更新与提交

入口:DataSet 变更记录与 DataAdapter。

动作:

  1. 调用 GetChanges() 获取所有修改过的行。
  2. 实例化 SqlCommandBuilder,这会根据 SelectCommand 的 SQL 自动生成 Insert、Update 和 Delete 命令(前提是 Select SQL 必须包含主键或唯一约束的列)。
  3. 调用 Update() 执行回写,该方法会根据行的 DataRowState 自动选择对应的 SQL 命令。
  4. 最后调用 AcceptChanges() 刷新内存状态。
DataSet dsChanged = ds.GetChanges();
if (dsChanged != null)
{
    SqlCommandBuilder builder = new SqlCommandBuilder(da);
    // 注意:Update 检测每条记录的行状态
    da.Update(ds, "Author"); 
    ds.AcceptChanges(); // 将 Added/Modified 标记为 Unchanged,移除 Deleted
}

关键方法对比:

  • AcceptChanges:提交更改。Added 和 Modified 行变为 Unchanged,Deleted 行被移除。
  • RejectChanges:撤销更改。Added 行被删除,Modified/Deleted 行恢复初始状态。

三、自定义 SQL 参数与映射

在使用 OleDb 或其他不支持自动生成的适配器时,需手动定义 Command。此时需关注 UpdatedRowSource 属性对输出参数的处理。

第4步:配置参数化插入

OleDbDataAdapter da = new OleDbDataAdapter();
OleDbCommand cmd = new OleDbCommand(
    "insert into [A_Emp_Dept_20190522](empname,line) values (?,?)", conn);

// 添加输入参数
OleDbParameter param1 = new OleDbParameter("empname", OleDbType.Char, 11, ParameterDirection.Input, false, 0, 0, "empname", DataRowVersion.Current, null);
OleDbParameter param2 = new OleDbParameter("line", OleDbType.Char, 11, ParameterDirection.Input, false, 0, 0, "line", DataRowVersion.Current, null);
cmd.Parameters.Add(param1);
cmd.Parameters.Add(param2);

da.InsertCommand = cmd;
// UpdatedRowSource 控制输出如何映射回 DataSet
// da.InsertCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;

DataSet ds = new DataSet();
ds.Tables[0].Rows.Add(new object[] { "222", "FBd" });
da.Update(ds);

UpdatedRowSource 选项说明

  • Both:允许映射输出参数和返回的第一行结果集。(默认值)
  • FirstReturnedRecord:仅映射返回结果集的第一行。
  • OutputParameters:仅映射输出参数。
  • None:忽略所有返回值和参数。

四、处理更新事件

在进行批量更新时,建议订阅 DataAdapter 的事件以进行日志记录或错误处理。

第5步:监听 RowUpdating 与 RowUpdated

RowUpdating 发生在数据库命令执行前,可用于取消当前操作或检查参数。

RowUpdated 发生在命令执行后,通常用于检查是否发生异常(Errors 属性)或确认影响的行数(RecordsAffected)。

SqlRowUpdatedEventArgs 常用属性:

  • Error/Errors:获取执行过程中的异常信息。
  • RecordsAffected:获取受影响(增删改)的行数。
  • Row:获取正在处理的 DataRow。
  • StatementType:当前执行的语句类型(Insert, Update, Delete)。
  • Status:获取命令执行的状态(如 Continue, SkipCurrentRow 等)。
以上就是 C# DataAdapter 在填充数据、执行更新以及处理相关事件方面的详细内容,更多关于 .NET 数据库交互优化与调试的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。