RowState 是 DataRow 很重要的一個(gè)屬性, 表示 DataRow 當(dāng)前的狀態(tài). RowState 有 Added, Modified, Unchanged, Deleted, Detached 幾種, 分別表示 DataRow 被添加, 修改, 無變化, 刪除, 從表中脫離. 在調(diào)用一些方法或者進(jìn)行某些操作之后, 這些狀態(tài)可以相互轉(zhuǎn)化. DataAdapter 可以根據(jù) RowState 來決定如何影響數(shù)據(jù)庫等存儲(chǔ)位置. 如果 DataRow 的狀態(tài)為 Added,DataAdapter 將把 DataRow 添加到數(shù)據(jù)庫等存儲(chǔ)位置, 對(duì)于 Modified, Deleted 則將執(zhí)行更新和刪除操作. 其實(shí), 最終的操作效果還是決定于 DataAdapter 的 SelectCommand, UpdateCommand 等 DbCommand. 如果, 在 UpdateCommand 中寫入 Delete 語句或者執(zhí)行有刪除操作的存儲(chǔ)過程, 那么狀態(tài)為 Modified 的 DataRow 最終將在數(shù)據(jù)庫中刪除而不是更新. DataTable.AcceptChanges的理解OleDbDataAdapter 怎么更新不了數(shù)據(jù)庫?
一個(gè)DataRow對(duì)象剛被創(chuàng)建之后其狀態(tài)是Detached,是孤立的一個(gè)存在,所以建立了DataRow之后在DataRow中的單元填充了數(shù)據(jù)后還要通過DataTable.Rows.Add(DataRow)方法將此DataRow添加到DataTable,DataRow添加到DataTable后, 這個(gè)DataRow的狀態(tài)就轉(zhuǎn)變?yōu)锳dded。當(dāng)修改了這個(gè)DataRow后,這個(gè)DataRow狀態(tài)轉(zhuǎn)為Modified,當(dāng)用DataRow.Delete()方法刪除DataRow后,DataRow狀態(tài)將轉(zhuǎn)為Deleted,不過此行還存在在DataTable中的,只是狀態(tài)改變了,這時(shí)用DataTable.Rows.Count查看行數(shù),跟刪除前是一樣的。只有在調(diào)用了DataTable.Remove(DataRow)方法后,此DataRow才被從DataTable移除,狀態(tài)也回復(fù)到Detached孤立狀態(tài)。
一旦調(diào)用了DataTable.AcceptChanges()方法后,所有的行將根據(jù)不同的狀態(tài)做不同的處理,Added、Modified、Unchanged將保留當(dāng)前值,不會(huì)改變,Deleted的行將從DataTable中移除,最后所有的行的狀態(tài)都置為Unchanged。當(dāng)DataTable是從DataAdapter.Fill(DataSet,DataTable)方法填充而形成的,F(xiàn)ill()方法將自動(dòng)調(diào)用AcceptChanges()方法,將DataTable的行狀態(tài)都置為Unchanged。并且,如果Fill方法中指定的那個(gè)DataTable在要填充的那個(gè)DataSet不存在時(shí),會(huì)生成一個(gè)跟數(shù)據(jù)源表同樣的結(jié)構(gòu)的DataTable并填充數(shù)據(jù)
用于從 DataTable 對(duì)象中刪除 DataRow 對(duì)象的方法有兩種:DataRowCollection 對(duì)象的 Remove 方法和 DataRow 對(duì)象的 Delete 方法。Remove 方法從 DataRowCollection 中刪除 DataRow,而 Delete 方法只將行標(biāo)記為刪除,當(dāng)應(yīng)用程序調(diào)用 AcceptChanges 方法時(shí),才會(huì)發(fā)生實(shí)際的刪除。通過使用 Delete,您可以在實(shí)際刪除之前先以編程方式檢查哪些行標(biāo)記為刪除。如果將行標(biāo)記為刪除,其 RowState 屬性會(huì)設(shè)置為 Deleted。
在將 DataSet 或 DataTable 與 DataAdapter 和關(guān)系型數(shù)據(jù)源一起使用時(shí),用 DataRow 的 Delete 方法移除行。Delete 方法只是在 DataSet 或 DataTable 中將行標(biāo)記為 Deleted,而不會(huì)移除它。而 DataAdapter 在遇到標(biāo)記為 Deleted 的行時(shí),會(huì)執(zhí)行其 DeleteCommand 方法以在數(shù)據(jù)源中刪除該行,但要在 DataSet 或 DataTable 中刪除該行就要用 AcceptChanges 方法永久移除該行。如果使用 Remove 刪除該行,則該行將從表中完全移除,但 DataAdapter 不會(huì)在數(shù)據(jù)源中刪除該行。
如何使用DataSet,在數(shù)據(jù)庫中增加、修改、刪除一個(gè)數(shù)據(jù)
首先我們打開一個(gè)連接
string MyConnString = "Driver={Microsoft Access Driver (*.mdb)}; DBQ=c:/test/test.mdb;";
string strComm = "select * from UserList"; SqlConnection conn = new SqlConnection(MyConnString); SqlDataAdapter MyComm = new SqlDataAdapter(strComm,MyConnection); 這里我們?yōu)榱酥v解方便,只在DataSet存入一個(gè)表的內(nèi)容:
DataSet MyDataSet = new DataSet();
MyComm.Fil(MyDataSet,"UserList"); 此時(shí)我們就獲得了一個(gè)擁有UserList表數(shù)據(jù)的DataSet。在講解DataSet之前,我們還需要了解DataSet的結(jié)構(gòu)下面是DataSet的結(jié)構(gòu)樹
DataSet
RelationsCollection ExtendedProperties TablesCollection DataTables Rows Columns 其它 由于我們研究的是DataTable,其它的我們暫時(shí)不管他們。一個(gè)DataSet中包含多個(gè)DataTable,一個(gè)DataTable又包含有多個(gè)Row,這就是我們操作DataSet的基礎(chǔ)啦: 添加數(shù)據(jù)
添加一數(shù)據(jù),從上面的列表中我們可以看出,其實(shí)就是添加一行Row,這里我們也來演示一下如何添加一行數(shù)據(jù),我們程序一切以DataSet為頂點(diǎn),呵呵,如果TablesCollection,RowsCollection下去的話,還有一些煩人的dt.AcceptChanges這些方法的調(diào)用,很煩人,還是一次搞定吧。
DataRow dr=MyDataSet.Tables["UserList"].NewRow();
dr["UserName"] = "周訊"; dr["ReMark"] = "100"; dr["Comment"] = "漂亮MM"; MyDataSet.Tables.Rows.Add(dr); 第一行,我們建立一個(gè)新的數(shù)據(jù)行,它用來儲(chǔ)存我們新加入的數(shù)據(jù)。然后我們?cè)谶@個(gè)數(shù)據(jù)行中加入我們需要的數(shù)據(jù)。dr["UserName"]表明是對(duì)UserName字段進(jìn)行添加,你可以使用dr[1]來添加信息,但是這需要我們事先知道字段在數(shù)據(jù)表的位置,而且在不知道數(shù)據(jù)表結(jié)構(gòu)的情況很難知道我們添加的數(shù)據(jù)的對(duì)應(yīng)情況,所以還是用字段名為好。
最后我們使用RowsCollection的Add方法,將我們新建這一行加入到數(shù)據(jù)表中。
修改數(shù)據(jù)
知道如何添加數(shù)據(jù)后,修改數(shù)據(jù)也是很簡(jiǎn)單的事情了.
MyDataSet.Tables["UserList"].Rows[0]["UserName"]="飛刀大哥";
這樣我們就修改了第一行數(shù)據(jù)中的UserName字段。
刪除數(shù)據(jù)
刪除數(shù)據(jù),主要是使用RowsCollection提供的Delete方法,看下面的程序也是很簡(jiǎn)單的事情啦:
MyDataSet.Tables["UserList"],Rows[0].Delete();
MyDataSet.AcceptChange();//很重要,但在Add(),Update(),時(shí),要放在oleAdaper.Update(),之后
這一行數(shù)據(jù)就已經(jīng)被刪除了。
恢復(fù)數(shù)據(jù)
有時(shí)候我們添加/修改數(shù)據(jù)會(huì)出現(xiàn)錯(cuò)誤,這時(shí)候,就需要恢復(fù)原來的數(shù)據(jù)。下面的程序,顯示如何判斷是否有錯(cuò)誤發(fā)生:
if(MyDataSet.HasErrors)
{ MyDataSet.RejectChanges(); } 首先我們檢查DataSet中是否有錯(cuò)誤發(fā)生,如果有就使用RejectChanges()方法,恢復(fù)DataSet中的數(shù)據(jù)。注意這里恢復(fù)是在DataSet中所有表以及表中DataRow中的數(shù)據(jù),也就是在此交次操作的數(shù)據(jù)全部恢復(fù)。如果我們只需要恢復(fù)部分內(nèi)容,我們可以使用DataTable或DataRow的RejectChanges(),這里就不詳細(xì)講解了,使用方法和DataSet一樣,只是操作的對(duì)像不同而已。
探測(cè)DataSet是否有改動(dòng)
我們?cè)趯ataSet送交給數(shù)據(jù)庫去保存去,我們需要看看這個(gè)DataSet是否已經(jīng)被改動(dòng)了。如果沒有改動(dòng),我們也就沒有必要去修改數(shù)據(jù)庫了。
if(MyDataSet.HasChanges)
{ //保存 }else{ //不進(jìn)行任何操作 } 更新數(shù)據(jù)庫
我們上面的操作,都只是針對(duì)DataSet的,沒有操作數(shù)據(jù)庫,但是我們的目的還是要將數(shù)據(jù)保存到數(shù)據(jù)中去,所以我們這里就需要調(diào)用DataSetCommand的Update方法。下面的程序顯示如何將DataSet的數(shù)據(jù)交給數(shù)據(jù)庫。
MyComm.Update(MyDataSet);
很簡(jiǎn)單的一句,呵呵。這里要注意,如果一個(gè)DataSet中包含有多個(gè)表,而我們只更新一個(gè),那我們就必須寫明更新的數(shù)據(jù)表名:
MyComm.Update(MyDataSet,"UserList");
當(dāng)Update方法被調(diào)用后,DataSetCommand會(huì)將數(shù)據(jù)庫中的數(shù)據(jù)與DataSet中的數(shù)據(jù)相比較,對(duì)不相同的地方進(jìn)行更新。
對(duì)于DataSet的操作,我們這里只講這么多,其實(shí)DataSet的方法和屬性有很多,功能也很全,我想現(xiàn)在這里的所講的功能,對(duì)一般的操作已經(jīng)足夠了。
|
|