對于剛剛學習ado.net數據訪問技術的來說,dataadapter也許往往會令他們感到迷惑,特別是習慣于利用托拽dataadapter控件進行開發的朋友,通過這一ado.net數據訪問控件,我們甚至不用書寫一行代碼,就能完成各種需要的數據訪問和操作,然而在享受快捷便利的同時,心中卻總掛著一絲意猶未盡的感覺。dataadapter控件在背后為我們做了怎樣的工作?弄清楚這一點,對于喜歡探根究底的朋友,不僅樂哉悠哉,也有利于我們更它的理解ado.net的數據訪問機制;同時對于.net為我們生成的有關數據訪問的一大堆莫名其妙的代碼,其中很多我們可能是用不到的,因此實在是感覺不爽,盡管在visual2005下.net已經利用局部類的機制將這些代碼很好的隱藏了起來。
在本篇文章中,我將自己手動寫代碼完成利用dataadapter進行數據訪問操作,以便能讓初學dataadapter的朋友明白它背后運行的一些情況。在此,我以sqlserver2005express數據庫作為數據源服務器,因此需要用到的是sqldataadapter數據訪問對象,對于其它的oledbdataadapter等對象與此是類似的,也希望這篇文章對于初學者能起到拋磚引玉的微薄作用吧。首先在sqlserver2005express里建立數據庫作為數據源,關于此過程的實現可以通過數據定義語句或直接利用可視化界面來完成。我們將通過datagridview控件來顯示數據,詳細的代碼如下所示:
public partial class form3 : form
{
private sqlconnection mycon;
private sqldataadapter myada;
private sqlcommand mycmd;
private sqlcommandbuilder mycbd;
private dataset myset;
public form3()
{
initializecomponent();
mycon = new sqlconnection("data source=localhost//sqlexpress;initial catalog=shop;persist security info=true;user id=sa;password= ");
myada = new sqldataadapter();
mycmd = new sqlcommand("select * from userinfo",mycon);
myada.selectcommand = mycmd;
mycbd = new sqlcommandbuilder(myada);
myset = new dataset();
myada.tablemappings.add("userinfo", "userinfo");
myada.tablemappings[0].columnmappings.add("userid", "用戶");
myada.tablemappings[0].columnmappings.add("username", "用戶姓名");
myada.tablemappings[0].columnmappings.add("userage", "年齡");
myada.tablemappings[0].columnmappings.add("usersex", "性別");
myada.tablemappings[0].columnmappings.add("useraddress", "地址");
}
private void form3_load(object sender, eventargs e)
{
try
{
myada.fill(myset, "userinfo");
}
catch (sqlexception ex)
{
messagebox.show(ex.tostring());
}
finally
{
mycon.close();
}
datagridview1.datasource = myset.tables["userinfo"];
}
private void bt_update_click(object sender, eventargs e)
{
try
{
//將更改的數據更新到數據表里
myada.update(myset.tables[0].getchanges());
messagebox.show("數據更新成功!");
//datatable接受更改,以便為下一次更改作準備
myset.tables[0].acceptchanges();
}
catch (sqlexception ex)
{
ex.tostring();
}
}
private void bt_delete_click(object sender, eventargs e)
{
//從datatable中刪除當前選中的行
myset.tables[0].rows[datagridview1.currentrow.index].delete();
if (messagebox.show("確定要刪除當前行數據?", "", messageboxbuttons.okcancel) == dialogresult.ok)
{
try
{
//將更改的數據更新到數據表里
myada.update(myset.tables[0].getchanges());
messagebox.show("數據刪除成功!");
//datatable接受更改,以便為下一次更改作準備
myset.tables[0].acceptchanges();
}
catch (sqlexception ex)
{
messagebox.show(ex.tostring());
}
}
else
{
//取消對datatable的更改
myset.tables[0].rejectchanges();
}
}
}
ok了,上面的代碼已經能夠完成對數據庫更新和刪除的操作,是不是也很簡潔,自己寫的才叫親切,才叫熟悉。下面來分析一下。
private sqlconnection mycon;
private sqldataadapter myada;
private sqlcommand mycmd;
private sqlcommandbuilder mycbd;
private dataset myset;
看看這幾句,這是干什么的,聲明了幾個引用類型的變量,讓它們引用什么啊?看一下變量類型的名字就很一目了然,像mycon是個sqlconnection類型,因此肯定是用來引用一個連接類型的,只是到此時此刻它們還未真正的引用任何東西罷了,就如母親孕育的孩子,呵呵,還未出世,親朋好友聚到一起,都為這事高興,先把名字給起好了。接著往下走,
mycon = new sqlconnection("data source=localhost//sqlexpress;initial catalog=shop;persist security info=true;user id=sa;password= ");
myada = new sqldataadapter();
mycmd = new sqlcommand("select * from userinfo",mycon);
myada.selectcommand = mycmd;
mycbd = new sqlcommandbuilder(myada);
myset = new dataset();
這幾句這么一寫,你的功勞可就大了,前面聲明的那幾個變量所引用的物件現在已經誕生了,像出世的孩子它們從這一刻起有了寶貴的生命。其實呢,通過工具箱拖控件的舉動基本上可以由到此為止的代碼給替換掉了,比如你拖了個sqlconnection控件,設置了連接信息屬性,就等于下面兩句代碼。只不過如今是咱自己很實在的構造出來滴,而拖個sqlconnection控件的話,是由微軟.net環境給你自動構造的,方式迥異,效果相同,心情不同。
private sqlconnection mycon ;
mycon = new sqlconnection("data source=localhost//sqlexpress;initial catalog=shop;persist security info=true;user id=sa;password= ");
這有關鍵的一句,有必要說一下
mycbd = new sqlcommandbuilder(myada);
這又是干什么滴?這得先說一下sqlcommandbuilder有什么妙用,我們從字面意思翻譯一下,sql就是sql,眾人名其曰結構化查詢語言;command,名令;builder,構造,建造,不太好,人家帶了個er,學過e文的都知道,這是個名詞,那就譯之為構造器,建造者能說得過去。sql命令構造器,這下恍然明白了,就是用來構造sql命令的,比如你更新數據庫需要一個update,通過這句它就給咱構造出來了。那么sql命令構造器這個東西又是怎么生成咱需要的sql語句命令的?它怎么知道我們要什么樣滴?其實它不知道,是我們給了它提示信息,不過它實在是太聰明了,就這么點提示信息人家就舉一反三,根據這點提示推斷出我們的需求。那我們在哪里給提示了,看這句myada.selectcommand = mycmd;我們把查詢的sql命令給了出來,給了dataadaper數據適配器的selectcommand,而我們又把dataadaper數據適配器(在這里為myada)作為參數丟給了sqlcommandbuilder,這下好了,被sqlcommandbuilder抓到了,它就這樣輕松加愉快的,根據抓到的dataadaper的selectcommand信息,一骨碌的把其它的sql操作命令都給生成出來了。可能有朋友問了,我不用這個命令構造器生成sql操作命令行不?當然是可以了,要是總覺得它自動給搞出來的不符合我們的要求,我們完全可以自己寫的靈活點,像下面這樣就可以了:
myada.deletecommand = new sqlcommand("delete * from userinfo where .....")
經過上面的這一番折騰,已萬事俱備,我們的數據適配器已經可以使用自身的利器sqlcommand對數據庫進行操作了;等等,有點問題,我們數據表里的字段名字起的都是英文,那么程序運行也是默認英文顯示,作為堂堂中國人,這點是不能原諒的,那有我們的方塊字看著賞心悅目。沒有關系,看下面代碼:
myada.tablemappings.add("userinfo", "userinfo");
myada.tablemappings[0].columnmappings.add("userid", "用戶");
myada.tablemappings[0].columnmappings.add("username", "用戶姓名");
myada.tablemappings[0].columnmappings.add("userage", "年齡");
myada.tablemappings[0].columnmappings.add("usersex", "性別");
myada.tablemappings[0].columnmappings.add("useraddress", "地址");
微軟也尊重我們,通過dataadaper給我們提供了tablemappings屬性,利用它就可以把數據庫里的千奇百怪的字段名毫不費力的給轉成我們需要的名字,人家這里稱作是映射。這下總算差不多了,我們要開始行動了,要對數據庫動刀了,開頭做了那么多準備,接下來就輕松了。首先是從數據表里查詢數據,就是我們慣用的select,myada.fill(myset, "userinfo");這句就行了,這么簡單?是啊,這里myada到底給我們做了什么?它做的也不少哦,它先要自動的把我們的數據庫連接打開,就是上面代碼中已經定義好的那個連接對象;完了尋覓到myada數據適配器的selectcommand命令,根據這個selectcommand命令去數據表里查詢數據,最后把提取到的數據放進了dataset(在此為myset)中的一個datatable(在此為userinfo)中,等到一切做完后,還會很負責任的把它自己打開的連接給關閉掉,哈哈,很不錯的一個家伙哦!查詢完成了,更新,刪除當然也是不在話下了,我們在datagridview控件中編輯完數據后,會首先將變化反映到關聯的dataset的datatable中,接下來還是數據適配器上場,直接調用它的update萬能方法就可以了,就會把我們的數據的更改寫到源數據表中了.這里萬能的背后仍然是dataadaper的sqlcommand命令,我們此前已經為它們配置好了,這里的一切就交給update方法吧.這里要羅索一下的是myset.tables[0].acceptchanges(),這句很有用,要不你更新一條后,接著再去更新第二條,第三條的話,就會出現異常,因為一次更新發生后,dataset會對本次更新掛起,到下一次更新的時候又會重復進行上一次掛起的更改,所以在每次更新后必須調用acceptchanges來清除掛起的更改.
仗著ado.net來對數據庫進行操作真的太方便了,方法也很多,熟練了會發現我怎么寫都能實現對數據庫的操作,一種很隨意的感覺.我這里對dataadapter搗弄了半天, 也只是羅嗦個皮毛,深入的內容咱再一起探究吧。
新聞熱點
疑難解答
圖片精選