简述DbDataAdapter.Update 方法
当应用程序调用 Update 方法时,DbDataAdapter 根据 DataSet 中配置的索引顺序为每一行检查 RowState 属性,并迭代执行所需的 INSERT、UPDATE 或 DELETE 语句。例如,由于 DataTable 中行的排序,Update 可能先执行一个 DELETE 语句,接着执行一个 INSERT 语句,然后再执行另一个 DELETE 语句。
应注意,这些语句不是作为批处理进程执行的;每一行都是单独更新的。在必须控制语句类型顺序的情况下(例如,INSERT 在 UPDATE 之前),应用程序可以调用 GetChanges 方法。
如果未指定 INSERT、UPDATE 或 DELETE 语句,Update 方法会生成异常。但是,如果设置 .NET Framework 数据提供程序的 SelectCommand 属性,则可以创建 SqlCommandBuilder 或 OleDbCommandBuilder 对象来为单个表更新自动生成 SQL 语句。然后,CommandBuilder 将生成其他任何未设置的 SQL 语句。此生成逻辑要求 DataSet 中存在键列信息。
Update 方法支持以下情况:DataSet 包含多个 DataTable 对象,而这些对象的名称只有大小写不同。当 DataSet 中有多个表具有相同的名称但大小写不同时,Update 执行区分大小写的比较以查找相应的表,如果不存在完全匹配的表,就会生成一个异常。下面的代码阐释该行为。
DataSet ds = new DataSet();
ds.Tables.Add("aaa");
ds.Tables.Add("AAA");
adapter.Update(ds, "aaa"); // Updates "aaa", which already exists in the DataSet.
adapter.Update(ds, "AAA"); // Updates "AAA", which already exists in the DataSet.
adapter.Update(ds, "Aaa"); // Results in an exception.
如果调用 Update 并且 DataSet 只包含一个其名称只有大小写不同的 DataTable,则更新该 DataTable。在这种情况下,比较不区分大小写。下面的 C# 代码阐释该行为。
DataSet dataset = new DataSet();
dataset.Tables.Add("aaa");
adapter.Update(dataset, "AAA"); // Updates table "aaa" because only one similarly named table is in the DataSet.
Update 方法在执行更新之前从第一个映射列出的表中检索行。然后,Update 使用 UpdatedRowSource 属性的值刷新该行。忽略返回的任何其他行。
UpdatedRowSource属性 获取或设置命令结果在由 DbDataAdapter 的 Update 方法使用时如何应用于 DataRow。默认的 UpdateRowSource 值为 Both,除非自动生成该命令(如 OleDbCommandBuilder 这样的情况),这时默认值为 None。在其他非自动生成命令情况下,不管使用代码还是通过查询设计器,通过设置命令的CommandText属性创建的命令对象都是默认值为Both。
成员名称
说明
Both
将输出参数和第一个返回行都映射到 DataSet 中的已更改的行。
FirstReturnedRecord
将第一个返回行中的数据映射到 DataSet 中的已更改的行。
None
忽略任何返回的参数或行。
OutputParameters
将输出参数映射到 DataSet 中的已更改的行。
在将任何数据加载回 DataSet 之后,将引发 OnRowUpdated 事件,从而允许用户检查经协调的 DataSet 行以及该命令返回的任何输出参数。在对一行成功进行更新之后,将接受对该行的更改。
当使用 Update 时,执行的顺序如下:
1. 将 DataRow 中的值移至参数值。
2. 引发 OnRowUpdating 事件。
3. 执行命令。
4. 如果该命令设置为 FirstReturnedRecord,返回的第一项结果将放置在 DataRow 中。
5. 如果存在输出参数,它们将被放在 DataRow 中。
6. 引发 OnRowUpdated 事件。
7. 调用 AcceptChanges。
与 DbDataAdapter 关联的每个命令通常都有一个与其关联的参数集合。参数通过 .NET Framework 数据提供程序的 Parameter 类的 SourceColumn 和 SourceVersion 属性映射到当前行。SourceColumn 引用 DataTable 列,而 DbDataAdapter 引用该列来获取当前行的参数值。
SourceColumn 在应用任何表映射之前将引用未映射的列名。如果 SourceColumn 引用一个不存在的列,则采取的操作取决于以下 MissingMappingAction 值之一。
n MissingMappingAction.Passthrough 如果不存在任何映射,则使用 DataSet 中的源列名和表名。
n MissingMappingAction.Ignore 生成 SystemException。当显式设置映射时,缺少输入参数的映射通常是由于出错所致。
n MissingMappingAction.Error 生成 SystemException。
SourceColumn 属性还用于将输出或输入/输出参数的值映射回 DataSet。如果它引用一个不存在的列,则会生成异常。
.NET Framework 数据提供程序的 Parameter 类的 SourceVersion 属性确定使用列值的哪个版本:Original、Current 还是 Proposed。该功能通常用于在 UPDATE 语句的 WHERE 子句中包含初始值,以检查开放式并发冲突。
注意 如果在更新行时出错,则会引发异常并停止执行更新。若要在遇到错误时继续更新操作而不生成异常,请在调用 Update 之前将 ContinueUpdateOnError 属性设置为 true。您还可以在 SqlDataAdapter 或 OleDbDataAdapter 的 RowUpdated 事件中逐行对错误作出响应。若要在 RowUpdated 事件中继续更新操作而不生成异常,请将 RowUpdatedEventArgs 的 Status 属性设置为 Continue。