|
本文想借用故事的方式來(lái)說(shuō)一下ADO.NET的工作方式。雖然現(xiàn)在都ORM了,但是了解一下ADO.NET還是有必要的。
在茫茫的大海上有許多的島,其中一個(gè)島的名字叫做“應(yīng)用程序島”。這座島上商業(yè)非常發(fā)達(dá),高樓大廈、店鋪林立。但是島的面積不夠大,沒(méi)有地方建立倉(cāng)庫(kù)。所以市長(zhǎng)決定,把臨近的一座小島開(kāi)發(fā)出來(lái),專(zhuān)門(mén)作為數(shù)據(jù)倉(cāng)庫(kù)來(lái)使用,這座島的名字就叫“數(shù)據(jù)庫(kù)島”。
市長(zhǎng)在數(shù)據(jù)庫(kù)島上面建立了一個(gè)MSSQL數(shù)據(jù)庫(kù),這樣各個(gè)商場(chǎng)、超市就可以把自己的貨物放進(jìn)去了。兩個(gè)島相鄰很近,為了便于運(yùn)輸,所以直接在兩個(gè)島之間建立了五座大橋。并且成了一個(gè)“數(shù)據(jù)訪問(wèn)池”的部門(mén)來(lái)專(zhuān)門(mén)管理這五座橋。
有一個(gè)叫command的家伙很聰明,覺(jué)得商機(jī)來(lái)了,于是他就成立了一家Command物流公司,專(zhuān)門(mén)負(fù)責(zé)兩座島之間的貨物運(yùn)輸。物流公司成立了幾個(gè)下屬部門(mén):Connection、DataReader。Connection負(fù)責(zé)與連接池的聯(lián)系,申請(qǐng)大橋的臨時(shí)使用權(quán),并且還要提供車(chē)輛。DataReader負(fù)責(zé)裝卸貨物。
好了,萬(wàn)事具備只欠東風(fēng)。物流公司成了好了之后就坐等客戶上門(mén)了。不久來(lái)了一位客戶,是島上的一個(gè)書(shū)店,他們購(gòu)進(jìn)了一批圖書(shū),需要送到數(shù)據(jù)庫(kù)島的倉(cāng)庫(kù)里。
【添加記錄的情況】
Command接到了這個(gè)任務(wù)很高興,終于開(kāi)張了。領(lǐng)導(dǎo)當(dāng)然不能自己親自去干活了,于是派出了明星員工cm007來(lái)負(fù)責(zé)這個(gè)任務(wù)。
SqlCommand cm007 = new SqlCommand();
Cm007從書(shū)店那里得到了指令(就是SQL語(yǔ)句)和貨物,來(lái)到Connection部門(mén)。
cm007.CommandText = "";
Connection部門(mén)派出了得力員工cn007
SqlConnection cn007 = new SqlConnection();
cm007.Connection = cn007;
cn007開(kāi)著車(chē),帶著cm007來(lái)到了大橋,由cn007和連接池聯(lián)系,想要申請(qǐng)一座大橋的臨時(shí)使用權(quán)。
cn007.Open();
連接池得到了這個(gè)申請(qǐng)之后,查看了一下大橋的使用情況,現(xiàn)在五座大橋都沒(méi)有人使用,于是把001號(hào)大橋的使用權(quán)交給了cn007。這個(gè)時(shí)候,這座001號(hào)大橋就由cm007他們獨(dú)占了,其他任何人都不可以使用。而且是按照獨(dú)占時(shí)間來(lái)收取費(fèi)用的。
一行人通過(guò)001號(hào)大橋來(lái)到了數(shù)據(jù)庫(kù),cm007把指令交給了數(shù)據(jù)庫(kù)管理員開(kāi)始交貨。數(shù)據(jù)庫(kù)管理員按照指令,把貨物放到了指定的位置。辦好之后cm007帶著數(shù)據(jù)庫(kù)的確認(rèn)證明,從大橋返回到了應(yīng)用程序島。離開(kāi)大橋后,cn007又給連接池發(fā)了一個(gè)申請(qǐng)。
cn007.Close();
連接池得到了這個(gè)申請(qǐng)后,收回了001號(hào)大橋的使用權(quán),這樣其他人就又可以使用這個(gè)大橋了。
cm007一行人來(lái)到了書(shū)店,把數(shù)據(jù)庫(kù)管理員的證明交給了書(shū)店,客戶很滿意,這個(gè)任務(wù)也就完成了。回到物流公司交差。
cn007.Dispose();
cm007.Dispose();
command很高興,首戰(zhàn)告捷,以后的生意一定會(huì)很紅火呀。
【提取(查詢)記錄,向上層直接返回DataReader的情況】
第二天,那家書(shū)店又來(lái)找command,要從數(shù)據(jù)庫(kù)島提五本書(shū)過(guò)來(lái)。又來(lái)生意了,太好了,于是又派出了cm007和cn007。不過(guò)這次和昨天不太一樣,昨天是送貨到倉(cāng)庫(kù),今天是從倉(cāng)庫(kù)提貨。這次還需要DataReader派裝卸工來(lái)配合。
輕車(chē)熟路,cn007開(kāi)著車(chē)帶著大家來(lái)到了大橋,cn007申請(qǐng)了一座大橋的使用權(quán),來(lái)到了數(shù)據(jù)庫(kù)島,cm007把指令交給了數(shù)據(jù)庫(kù)管理員開(kāi)始提貨。不過(guò)這次卻遇到了一點(diǎn)小問(wèn)題,運(yùn)輸車(chē)的運(yùn)載量的太小了,一次只能運(yùn)一本書(shū)(一條記錄)。可是這次卻需要提五本書(shū)(五條記錄),沒(méi)辦法,只好多跑幾趟了。
帶上一本書(shū)(一條記錄),來(lái)到了書(shū)店,書(shū)店老板很高興,這么快就到了呀,趕快卸貨上架吧。咦等等,怎么只有一本書(shū)呀。Cm007只好解釋?zhuān)覀兊能?chē)運(yùn)載量太小了,一次只能運(yùn)一條記錄,不過(guò)速度還是很快的呀。
書(shū)店老板想了想,也湊合了,那你們趕快運(yùn)下一條記錄吧。
如是這般,折騰了五趟,總算把貨物全都運(yùn)完了。
“等等”,cn007說(shuō),“大橋的使用權(quán)還沒(méi)有交回去呢。”于是大家又來(lái)到了橋頭,把使用權(quán)交了回去。
最后回到物流公司交差。
【改進(jìn),向上層返回DataTable】
這回command可高興不起來(lái)了。大橋是按照占用時(shí)間來(lái)收費(fèi)的,這么來(lái)回折騰,大橋的占用時(shí)間明顯變長(zhǎng)了,這就增加了成本呀。另外現(xiàn)在汽油這么貴,來(lái)回折騰燒的可都是錢(qián)呀,就不能跑一趟多運(yùn)點(diǎn)嗎?
于是command把大家召集過(guò)來(lái)一起商量這個(gè)事情。cn007說(shuō),大橋這一段沒(méi)有什么辦法可想了,一次只能運(yùn)出來(lái)一條記錄,這個(gè)也不知道是誰(shuí)規(guī)定的,我們也改不了。不過(guò)從橋頭到客戶那里我們倒是可以想想辦法,我有一個(gè)朋友,DataAdapter,他們也許會(huì)有辦法。Command聽(tīng)了也沒(méi)有什么其他的方法,那就把DataAdapter請(qǐng)過(guò)來(lái),一起商量一下吧。
第二天,DataAdapter過(guò)來(lái)了,也帶來(lái)了他的解決方案。其實(shí)也很簡(jiǎn)單,他們公司可以提供集裝箱(就是DataTable),在橋頭等待,貨物運(yùn)到的時(shí)候由DataReader裝到集裝箱里,然后立刻返回運(yùn)第二批貨物。等需要的貨物全都裝完了之后,在開(kāi)著集裝箱運(yùn)到客戶那里。
SqlDataAdapter da007 = new SqlDataAdapter();
DataTable dt007 = new DataTable();
da007.Fill(dt007);
這樣就節(jié)省了大橋的占用時(shí)間,節(jié)省了成本。到客戶的這段路程,集裝箱跑一趟就可以了,省油。
這個(gè)方案不錯(cuò),command欣然接受。
過(guò)了幾天,書(shū)店又要提一批圖書(shū),這次采用了集裝箱的方案,果然大大節(jié)省了成本,客戶也很滿意,雖然一開(kāi)始要等待比較長(zhǎng)的時(shí)間,但是好在一次性就可以得到全部的貨物。
【多種返回類(lèi)型:DataRow、object[]、object】
有一天又發(fā)現(xiàn)了一個(gè)新問(wèn)題,書(shū)店只要一本書(shū)。就一本書(shū),也弄一個(gè)集裝箱?太浪費(fèi)了吧。怎么辦?干脆直接用DataRow吧。實(shí)在不行用object[]。對(duì)于一條記錄也足夠用了。
【實(shí)體類(lèi)開(kāi)始登場(chǎng)】
于是物流公司的生意是越來(lái)越紅火了。有一家大型超市也找到了command,希望能夠?yàn)槌羞\(yùn)輸貨物。這可是一比大買(mǎi)賣(mài)呀,command當(dāng)然是很高興。大家一拍即合。
一開(kāi)始合作的也很愉快,但是過(guò)了幾天出現(xiàn)了一點(diǎn)小問(wèn)題。
【DataTable的缺點(diǎn)】
超市的老板找到了command,“你們的集裝箱確實(shí)挺好,但是有一個(gè)小問(wèn)題呀。他們的樣子都是一模一樣的,只能通過(guò)外面的標(biāo)簽來(lái)區(qū)分里面的貨物,這個(gè)太不方便了,而且還容易出錯(cuò),昨天本來(lái)想運(yùn)一批‘微波爐’,結(jié)果標(biāo)簽寫(xiě)錯(cuò)了,寫(xiě)成了‘光波爐’。幸好發(fā)現(xiàn)的及時(shí),否則就賠大發(fā)了。你們能不能想個(gè)好點(diǎn)的辦法呢?”。
command心想:“你們把標(biāo)簽寫(xiě)錯(cuò)了,和我有什么關(guān)系呢?”不過(guò)客戶就是上帝呀,得罪不起,還得想個(gè)辦法解決一下。
于是又把大家都召集過(guò)來(lái)一起商議。只是這次并沒(méi)有上次那么順利,想了不少辦法,但是都不理想。正在一籌莫展的時(shí)候,面向?qū)ο蠊镜耐其N(xiāo)員來(lái)了。
【實(shí)體類(lèi)來(lái)了】
面向?qū)ο蟮耐其N(xiāo)員知道了這個(gè)問(wèn)題后笑了(來(lái)生意了呀,哈)。“這個(gè)正是我們的優(yōu)勢(shì)呀,相對(duì)于集裝箱(DataTable)的容易出錯(cuò)這個(gè)缺點(diǎn),我們推出來(lái)‘實(shí)體類(lèi)’,這種新型的集裝箱,是根據(jù)不同的貨物量身定做的,微波爐的實(shí)體類(lèi)只能裝微波爐,光波爐的實(shí)體類(lèi)只能裝光波爐,冰箱的實(shí)體類(lèi)只能裝冰箱……而且他們的外形也和獨(dú)特,一眼就能看出來(lái),很好區(qū)分。”
Command一聽(tīng),這個(gè)好哇,正愁這件事情呢,太好了。“我們正在和一家大型超市合作,他們的貨物有很多的種類(lèi),每一類(lèi)都定制一個(gè)實(shí)體類(lèi),這樣不就不會(huì)出錯(cuò)了嗎?哈哈。快把超市老板找來(lái)一起商議一下。”
【不僅實(shí)體類(lèi)來(lái)了,還帶來(lái)了一批專(zhuān)門(mén)的裝卸工人】
但是事實(shí)和理想總是有那么一點(diǎn)差距。以前用集裝箱(DataTable)的時(shí)候,結(jié)構(gòu)是一樣的,DataAdapter只需要一種工人就可以完成裝卸的工作,但是采用實(shí)體類(lèi)之后,就必須按照實(shí)體類(lèi)的各自的特點(diǎn)來(lái)找人。
能夠給冰箱實(shí)體類(lèi)裝貨物的工人,不能給電視實(shí)體類(lèi)裝貨物,因?yàn)閮煞N實(shí)體類(lèi)的結(jié)構(gòu)是不一樣的。同理也不能給其他實(shí)體類(lèi)裝卸貨物。這樣就需要很多工人,一批工人專(zhuān)門(mén)裝卸冰箱實(shí)體類(lèi),另一批工人專(zhuān)門(mén)裝卸電視實(shí)體類(lèi)……。
問(wèn)題還不只這些,一開(kāi)始超市大量提取CRT顯示器,但是過(guò)了一段時(shí)間基本不提取CRT顯示器的,因?yàn)楸灰壕э@示器代替了。Command本來(lái)想去掉CRT的實(shí)體類(lèi)和其裝運(yùn)工人,但是超市說(shuō)了,雖然現(xiàn)在不怎么賣(mài)CRT了,但是還是有需求的呀。你裁掉了,下個(gè)月想運(yùn)CRT顯示器怎么辦呀?
這樣成本就又上來(lái)了。而且很可能養(yǎng)著一批工人,但是他們又沒(méi)什么事情可干。
Command愁壞了,想要改回集裝箱,但是客戶又不同意,實(shí)體類(lèi)很好用呀,你怎么可以改回不好用的集裝箱呢?
這可怎么辦?成本居高不下,快賠死了。
【“反射”登場(chǎng)了】
這時(shí)候又來(lái)了一個(gè)推銷(xiāo)員。(怎么推銷(xiāo)員這么多呢?)
這次是反射公司的推銷(xiāo)員,他帶來(lái)了一個(gè)叫做“反射”的東東,用了這個(gè)就不怕不同類(lèi)型的實(shí)體類(lèi)了,因?yàn)橛昧朔瓷洌慌と司涂梢越o不同類(lèi)型的實(shí)體類(lèi)賦值了,不在需要向以前那樣,不同的實(shí)體類(lèi)需要不同的工人了。
太好了,這樣就不需要那么多不同類(lèi)型的工人了,成本又可以降低下來(lái)了。
故事就先到這里吧,再往下就應(yīng)該說(shuō)一說(shuō)反射的效率問(wèn)題了,但是這方面我還沒(méi)有做過(guò)測(cè)試,理論上更是不清楚。所以就先不說(shuō)了。
這個(gè)只能算是故事梗概吧,讀起來(lái)很是干干巴巴的,沒(méi)什么味道。俺語(yǔ)文沒(méi)學(xué)好,文筆很差。這里表達(dá)的重點(diǎn)有兩個(gè)。
一個(gè)是Connection和連接池的關(guān)系,Connection、Command、DataReader、DataAdapter他們的關(guān)系。我把Command看成了一個(gè)大的容器,在故事里是一個(gè)物流公司,其他的是下屬部門(mén)或者是合作伙伴。
另一個(gè)是DataTable和實(shí)體類(lèi)。只是這一點(diǎn)說(shuō)得并不是很詳細(xì),他們的優(yōu)缺點(diǎn)說(shuō)得也不多。
目前就只想到了這些。后一篇就是代碼篇了。
NET技術(shù):重溫?cái)?shù)據(jù)庫(kù)訪問(wèn)——故事篇,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。