2023年11月26日发(作者:)

C#使⽤DataSetDatatable更新数据库的三种实现⽅法

本⽂以实例形式讲述了使⽤DataSet Datatable更新数据库的三种实现⽅法,包括CommandBuilder ⽅法、DataAdapter 更新数据源以及使⽤sql语句更新。分享给

⼤家供⼤家参考之⽤。具体⽅法如下:

⼀、⾃动⽣成命令的条件 CommandBuilder ⽅法

a)动态指定 SelectCommand 属性

b)利⽤ CommandBuilder 对象⾃动⽣成 DataAdapter DeleteCommandInsertCommand UpdateCommand

c)为了返回构造 INSERTUPDATE DELETE SQL CommandBuilder 必须执⾏ SelectCommand

即:必须额外经历⼀次到数据源的⾏程,这可能会降低性能。这也是⾃动⽣成命令的缺点。

d)SelectCommand 还必须返回⾄少⼀个主键或唯⼀列.

CommandBuilderDataAdapter关联时,就会⾃动⽣成DeleteCommandInsertCommand UpdateCommand中为空的命令。即不空的不⽣成。

e)必须是⼀个表,SELECT的不能是多个表的联合。

动⽣成命令的规则:

在数据源处为表中所有 RowState Added 的⾏插⼊⼀⾏(不包括标识、表达式或时间戳等列)

Modified 的⾏更新⾏(列值匹配⾏的主键列值)

Deleted 的⾏删除⾏(列值匹配⾏的主键列值).这就是为什么要求条件c.d

注意:

a)因为从SELECT数据到UPDATE数据,中间这段时间有可能别的⽤户已经对数据进⾏了修改。⾃动⽣成命令这种UPDATE只对在⾏包含所有原始值并且尚未从数

据源中删除时更新。

b)⾃动命令⽣成逻辑为独⽴表⽣成 INSERTUPDATE DELETE 语句,⽽不考虑与数据源中其他表的任何关系。因此,当调⽤ Update 来为参与数据库中外键

约束的列提交更改时,可能会失败。若要避免这⼀异常,请不要使⽤ CommandBuilder 来更新参与外键约束的列,⽽应显式地指定⽤于执⾏该操作的语句。

下⾯是⾃动⽣成命令的例⼦

// Assumes that connection is a valid SqlConnection object.

SqlDataAdapter adapter = new SqlDataAdapter(

"SELECT * FROM ers", connection);

SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

refix = "[";

uffix = "]";

DataSet custDS = new DataSet();

();

(custDS, "Customers");

// Code to modify data in the DataSet here.

// Without the SqlCommandBuilder, this line would fail.

(custDS, "Customers");

();

⼆、使⽤ DataAdapter 更新数据源

需要注意:

a)如果 SelectCommand 返回 OUTER JOIN 的结果,则 DataAdapter 不会为⽣成的 DataTable 设置 PrimaryKey 值。您必须⾃⼰定义PrimaryKey 以确保正确解析

重复⾏.

b)如果对 DataSetDataTable DataRow 调⽤ AcceptChanges,则将使 DataRow 的所有 Original 值都将被重写为该 DataRow Current 值。如果已修改将该

⾏标识为唯⼀⾏的字段值,那么当调⽤ AcceptChanges 后,Original 值将不再匹配数据源中的值。

看看下⾯例⼦:

// Assumes connection is a valid SqlConnection.

SqlDataAdapter dataAdpater = new SqlDataAdapter(

"SELECT CategoryID, CategoryName FROM Categories", connection);

Command = new SqlCommand(

"UPDATE Categories SET CategoryName = @CategoryName " +

"WHERE CategoryID = @CategoryID" , connection);

(

"@CategoryName", ar, 15, "CategoryName");

SqlParameter parameter = (

"@CategoryID", );

Column = "CategoryID";

Version = al;

DataSet dataSet = new DataSet();

(dataSet, "Categories");

DataRow row = ["Categories"].Rows[0];

row ["CategoryName"] = "New Category";

(dataSet, "Categories");

插⼊、更新和删除的排序

在许多情况下,以何种顺序向数据源发送通过 DataSet 作出的更改是相当重要的。

例如,如果已更新现有⾏的主键值并且添加了具有新主键值的新⾏,则务必要在处理插⼊之前处理更新。

可以使⽤ DataTable Select ⽅法来返回仅引⽤具有特定 RowState DataRow 数组。然后可以将返回的 DataRow 数组传递到 DataAdapter Update ⽅法来

处理已修改的⾏。通过指定要更新的⾏的⼦集,可以控制处理插⼊、更新和删除的顺序。

⽰例如下:

DataTable table = ["Customers"];

// First process deletes.

((null, null, d));

// Next process updates.

((null, null,

edCurrent));

// Finally, process inserts.

((null, null, ));

三、使⽤sql语句更新

例如:

cmd = new OleDbCommand((@"insert into worker(workerid,workername,password,phoneno) values ('{0}','{1}','{2}','{3}') ", , , , ),oc);

();

try

{

int i = eNonQuery();

}

catch (Exception ex)

{

}

性能的优劣及使⽤的情形,还未完全明⽩。

⼀般的,绑定bindingsource,⽤datatable绑定bindingsource (实质上绑定的是datatabledefaultview,同时可⽤到dataview的筛选功能,但是在筛选完后,filter

要重置为null,否则出现的⼀直是经过筛选的数据)

其他:

使⽤builder 的作⽤:

OleDbCommandBuilder cb = new OleDbCommandBuilder(da);

这个主要是为了让C#⾃动为OleDbDataAdapter da⽣成相对应的DeleteCommand,UpdateCommand!

希望本⽂所述对⼤家的C#数据库程序设计有所帮助。