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