1. 程式人生 > >[C#]使用DataSet Datatable 更新資料庫的三種方式

[C#]使用DataSet Datatable 更新資料庫的三種方式

1:自動生成命令的條件 CommandBuilder 方法
a)動態指定 SelectCommand 屬性
b)利用 CommandBuilder 物件自動生成 DataAdapter 的 DeleteCommand、InsertCommand 和 UpdateCommand。
c)為了返回構造 INSERT、UPDATE 和 DELETE 。SQL CommandBuilder 必須執行 SelectCommand。
即:必須額外經歷一次到資料來源的行程,這可能會降低效能。這也是
自動生成命令的缺點。
d)SelectCommand 還必須返回至少一個主鍵或唯一列.
當CommandBuilder和DataAdapter關聯時,就會自動生成DeleteCommand、
InsertCommand 和 UpdateCommand中為空的命令。即不空的不生成。
e)必須是一個表,SELECT的不能是多個表的聯合。

#動生成命令的規則#
在資料來源處為表中所有 RowState 為 Added 的行插入一行(不包括標識、表示式或時間戳等列)。
為 Modified 的行更新行(列值匹配行的主鍵列值) 。
Deleted 的行刪除行(列值匹配行的主鍵列值).這就是為什麼要求條件c.d
注意:
a)因為從SELECT資料到UPDATE資料,中間這段時間有可能別的使用者已經對資料進行了修改。
自動生成命令這種UPDATE只對在行包含所有原始值並且尚未從資料來源中刪除時更新。
b)自動命令生成邏輯為獨立表生成 INSERT、UPDATE 或 DELETE 語句,
而不考慮與資料來源中其他表的任何關係。因此,當呼叫 Update
來為參與資料庫中外來鍵約束的列提交更改時,可能會失敗。若要避免這一異常,
請不要使用 CommandBuilder 來更新參與外來鍵約束的列,而應顯式地指定用於執行該操作的語句。
下面是自動生成命令的例子
// Assumes that connection is a valid SqlConnection object.
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";

DataSet custDS = new DataSet();

connection.Open();
adapter.Fill(custDS, "Customers");

// Code to modify data in the DataSet here.

// Without the SqlCommandBuilder, this line would fail.
adapter.Update(custDS, "Customers");
connection.Close();

2:使用 DataAdapter 更新資料來源
注意:
a)如果 SelectCommand 返回 OUTER JOIN 的結果,則 DataAdapter
不會為生成的 DataTable 設定 PrimaryKey 值。您必須自己定義
PrimaryKey 以確保正確解析重複行.
b)如果對 DataSet、DataTable 或 DataRow 呼叫 AcceptChanges,
則將使 DataRow 的所有 Original 值都將被重寫為該 DataRow 的 Current 值。
如果已修改將該行標識為唯一行的欄位值,那麼當呼叫 AcceptChanges 後,
Original 值將不再匹配資料來源中的值。
下面例子
// Assumes connection is a valid SqlConnection.
SqlDataAdapter dataAdpater = new SqlDataAdapter(
"SELECT CategoryID, CategoryName FROM Categories", connection);

dataAdpater.UpdateCommand = new SqlCommand(
"UPDATE Categories SET CategoryName = @CategoryName " +
"WHERE CategoryID = @CategoryID" , connection);

dataAdpater.UpdateCommand.Parameters.Add(
"@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");

SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
"@CategoryID", SqlDbType.Int);
parameter.SourceColumn = "CategoryID";
parameter.SourceVersion = DataRowVersion.Original;

DataSet dataSet = new DataSet();
dataAdpater.Fill(dataSet, "Categories");

DataRow row = dataSet.Tables["Categories"].Rows[0];
row ["CategoryName"] = "New Category";

dataAdpater.Update(dataSet, "Categories");
------------------------------------------------------------------------------------------------
插入、更新和刪除的排序
在許多情況下,以何種順序向資料來源傳送通過 DataSet 作出的更改是相當重要的。
例如,如果已更新現有行的主鍵值並且添加了具有新主鍵值的新行,
則務必要在處理插入之前處理更新。

可以使用 DataTable 的 Select 方法來返回僅引用具有特定 RowState 的 DataRow 陣列。
然後可以將返回的 DataRow 陣列傳遞到 DataAdapter 的 Update 方法來處理已修改的行。
通過指定要更新的行的子集,可以控制處理插入、更新和刪除的順序。
DataTable table = dataSet.Tables["Customers"];

// First process deletes.
adapter.Update(table.Select(null, null, DataViewRowState.Deleted));

// Next process updates.
adapter.Update(table.Select(null, null,
DataViewRowState.ModifiedCurrent));

// Finally, process inserts.
adapter.Update(table.Select(null, null, DataViewRowState.Added));

3.使用sql語句更新

例如:

 cmd = new OleDbCommand(string.Format(@"insert into worker(workerid,workername,password,phoneno) values ('{0}','{1}','{2}','{3}') ", textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text),oc);
            oc.Open();
            try
            {
                int i = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
 
            }

 效能的優劣及使用的情形,還未完全明白。

一般的,繫結bindingsource,用datatable繫結bindingsource (實質上繫結的是datatable。defaultview,同時可用到dataview的篩選功能,但但在篩選完後,filter要重置為null,否則出現的一直是經過篩選的資料)詳見bindingsource 文章

其他:

1.使用builder 的作用:

OleDbCommandBuilder cb = new OleDbCommandBuilder(da);
這個主要是為了讓C#自動為OleDbDataAdapter da生成相對應的DeleteCommand,UpdateCommand!