使用ADO.NET輕松操縱數據庫(二)
2024-07-21 02:07:54
供稿:網友
首先,ado.net中使用了dataadapter 來處理與數據庫的聯機與脫機。當時開發人員設計了dataadapter是為了能夠處理脫機數據,方便操作,關于這一點,只要調用其fill()方法即可,這時會在dataset中創建一個新的名為“table“的datatable.要重新指定名可用dataadapter.fill(dataset,“tabelname“)。此時connection也關閉了。dataadapter既可以用來提交查詢,并將結果存儲到dataset中,也可以用來向數據庫傳遞更改。僅僅使用其update方法即可達到向數據庫提交存儲地datset中的更改。
dataadapter將查詢的結果存儲在dataset或datatable對象中,當執行這一過程的時候,dataadapter使用了一個command來與數據庫通訊,并在內部使用了datareader來獲取查詢結果,最后才將結果復制到dataset新行中去。這也是fill的過程。如果有兩個dataadapter對象,都使用相同的connection對象,在創建的時候就會創建兩個connection對象,而不是同一個,這種情況的解決方案是:
sqlconnection con=new sqlconnection("server=localhost;database=northwind;trusted_connection=yes;")
sqldataadapter da=new sqldataadapter("select categoryid,description from categories",con);
sqldataadapter da=new sqldataadapter("select categoryid,description from customers",con);
而不是將查詢字符串,單獨寫成一行。
有時候可能并不希望dataset中的架構與數據庫中的架構相同,這種情況的解決方案之一是可以采用別名的方法,即select id as product id,amount as product amount from product;另外一種解決方案就是使用dataadapter提供的tablemappings集合機制,通過它就可以將查詢結果映射到dataset結構中,這種方法更方便,更靈活。tablemappings屬性返回一個datatablemappingscollection對象,其中包含了一組datatablemappings,只要dataset中相應的表名稱與數據庫中的表名相同,即可以使用它來創建一個映射(dataset中可以有多個表)。tablemappings里還有一個columnmappings屬性,其用法與tablemappings相似。其原理是dataadapter從數據庫讀取數據后,利用datareader從結果集中獲取列名稱,有一點特別要注意,即只能獲取列名稱而無法獲取表名稱,dataadapter事先假定表名稱為table,接著遇到映射語句則進行表映射。不說了,看代碼:
datacolumnmapping colmap;
sqlconnection con=new sqlconnection("server=localhost;database=northwind;trusted_connection=yes;");
sqldataadapter da=new sqldataadapter("select categoryid,description from categories",con);
dataset ds=new dataset();
datatablemapping tblmap=da.tablemappings.add("table","ca"); //這里table為關鍵,映射表名為ca
colmap=tblmap.columnmappings.add("categoryid","id"); //映射列表
colmap=tblmap.columnmappings.add("description","描述");
// response.write(tblmap.datasettable.tostring());
da.fill(ds);
datatable dt=ds.tables["ca"]; //這里是映射后的表名,如果仍為數據庫的表名,則無效,特別注意
this.datagrid1.datasource=dt;
this.datagrid1.databind();
運行代碼后就會發現datagrid1上的列名為id和描述 (^_^)
(注:使用datatablemapping 之前要前導入名空間system.data.common;)
還可以使用addrange方法來簡化表和列的映射:(一些代碼同上面)
.......
datatablemapping tblmap=da.tablemappings.add("table","ca"); datacolumnmapping[] colmaparray=new datacolumnmapping[]{new datacolumnmapping("categoryid","產 品號"),new datacolumnmapping("description","描述")}; tblmap.columnmappings.addrange(colmaparray);
......
這種映射關系只能從數據庫中讀取展示給用戶,如果要將映射后的table的更改提交給數據庫,這時庫發現其中列與庫中列不同,便會發生異常,dataadapter 同時也提供了missingmappingaction屬性來處理。
dataadapter1.missingmappingaction=missingmappingaction.passthrough/ignore/error
它接受missingmappingaction的枚舉值,passthrough這個值表示如果在庫中找不到與dataset中相同列的話,就將此列映射到庫中,ignore枚舉值表示忽略示出現的列,error表示找不到相應的列則拋出異常。
分頁:
分頁在應用中是常有的事,而dataadapter本身也提供了分頁的簡單功能,如:dataadapter1.fill(dataset,startrow,rownum,“tablename“)這種功能用于數據量較小的查詢就可以,但當有大量數據的時候,就會發現這種分頁的問題的存在。它的原理是假如有一百行數據,分成十頁,每頁十行,當獲取每一頁的時候,返回前10行,再接著,第二頁,刪除了前10行而獲取接下的10行,在這一次中,只是為了獲?。保靶袛祿珨祿靺s返回了20行,依此類推,第10頁的時候就會返回100行,而dataadapter本身就幫我們刪除了90行,因為我們看上去返回的還是10行,這種性能太低。因此本篇繼續介紹另外一種性能較高的分頁方法。實際上這種分頁方法是將上一頁最后一行的鍵值存儲下來,直接在sql語句中就過濾掉了,不象前面那種到dataadapter這邊才過濾掉。例:
con=new sqlconnection("server=localhost;database=northwind;trusted_connection=yes;");
da=new sqldataadapter("select top 50 customerid,companyname from customers where customerid>'bottm'",con);
ds=new dataset();
da.fill(ds,"categories");
this.datagrid1.datasource=ds.tables["categories"]; this.datagrid1.databind();
con.close();
這里假如上一頁最后一個鍵值為”bottm”,可以將它用參數替代掉,這樣就查出了在'bottm'之后的50行。這種方法實現簡單效率也高。