詳解C#下數(shù)據(jù)庫(kù)編程
C#下數(shù)據(jù)庫(kù)編程前言:
曾幾何時(shí),OO語(yǔ)言大家族中又多了一位新成員,他有個(gè)堅(jiān)強(qiáng)、銳利而又不失好聽(tīng)的名字,C#(讀做C Sharp)。C#由Microsoft一手打造,更重要的是其總設(shè)計(jì)師就是Turbo Pascal、Delphi的締造者、天才的Anders。記得在一次C#的演示會(huì)上,Anders和Microsoft的主管人員曾立下壯志,要讓C#取代VC++,成為今后.NET研發(fā)的最佳選擇語(yǔ)言。但后來(lái)的許多負(fù)面的議論也不免讓人對(duì)這個(gè)C#表示懷疑,有人說(shuō)C#就是Java的翻版,幾乎沒(méi)有什么自己的特點(diǎn),更有人說(shuō)C#效率低下,而且和VB.NET有非常大類(lèi)同,根本就沒(méi)有意義推出,不久就會(huì)下臺(tái)并最終死亡,等等。我們也不禁懷疑起來(lái),C#真的這么命短?真的會(huì)和Java沒(méi)有什么大的交鋒就英年早逝?
兩年多過(guò)去了,這種議論大部分已隨著事實(shí)不攻自破。C#不僅沒(méi)有死亡,而且有著超乎尋常的生命力,正在用他鋒利的語(yǔ)言利劍,讓世人真正領(lǐng)教了什么叫做系出名門(mén)、天生立志。在.NET平臺(tái)研發(fā)上,C#已成為無(wú)可爭(zhēng)議的最佳選擇語(yǔ)言,更令人吃驚的是,這個(gè)人稱(chēng)和Java雷同的"仿制品"語(yǔ)言卻不知道為什么,一步步在蠶食Java的地盤(pán),令Java的締造者已開(kāi)始感到不安,更讓Java的使用者或多或少有些動(dòng)搖。
大約1年前,我接觸到了C#,并且試著以我一貫審視IT界發(fā)展的眼光去審視他。通過(guò)一些日子的學(xué)習(xí)和體會(huì),我確實(shí)感覺(jué)這個(gè)語(yǔ)言的不平凡性,特別是他充分利用了.NET的優(yōu)勢(shì)和特點(diǎn),并有VS.NET的完美集成于.NET研發(fā)平臺(tái)中。在我長(zhǎng)年研發(fā)的數(shù)據(jù)庫(kù)領(lǐng)域,我試著用C#結(jié)合ADO.NET研發(fā)了一些項(xiàng)目?,F(xiàn)借這個(gè)機(jī)會(huì),和讀者們一起分享C#研發(fā)數(shù)據(jù)庫(kù)的快樂(lè)。
C#下數(shù)據(jù)庫(kù)編程正文:
如果你以前用過(guò)Visual Foxpro研發(fā)數(shù)據(jù)庫(kù)項(xiàng)目,你就會(huì)有這種體會(huì),VFP對(duì)數(shù)據(jù)庫(kù)的操作,還是一種對(duì)數(shù)據(jù)庫(kù)文件的操作,比如:
- OPEN DATABASE MyDatabase &&打開(kāi)數(shù)據(jù)庫(kù)MyDatabase
- USE MyTable &&打開(kāi)數(shù)據(jù)庫(kù)中的MyTable表
- GO 5 &&將Cursor跳到第5條記錄
- REPLACE MyName WITH "楊揚(yáng)" &&用"楊揚(yáng)"替換第5條記錄上的MyName字段
- GO BOTTOM &&將Cursor跳到最后一條記錄
- LOCATE FOR MyName=="楊揚(yáng)" &&查找并定位
- IF FOUND()
- ? "FOUND!"
- ELSE
- ? "NOT FOUND!"
- ENDIF
- USE &&關(guān)閉MyTable
- CLOSE DATABASE MyDatabase &&關(guān)閉數(shù)據(jù)庫(kù)MyDatabase
這段小程式能說(shuō)是VFP中比較簡(jiǎn)單的一段小程式了,但非常有代表性。從這段程式我們能感覺(jué)到,在VFP想操縱一個(gè)數(shù)據(jù)庫(kù)中的一個(gè)表需要許多類(lèi)似文件的操作,比如:打開(kāi)數(shù)據(jù)庫(kù)、打開(kāi)表、跳轉(zhuǎn)Cursor、讀取字段內(nèi)容、查找字段內(nèi)容、關(guān)閉表、關(guān)閉數(shù)據(jù)庫(kù)等等。這些操作雖然直觀易懂,但十分不方便使用,而且如果同時(shí)有多個(gè)表打開(kāi),經(jīng)常會(huì)出現(xiàn)表的輪換訪問(wèn)的問(wèn)題,就需要不斷的轉(zhuǎn)換表的工作區(qū),十分的麻煩和容易出錯(cuò)。最關(guān)鍵的是,這種操作方法不符合OO思想的精華--封裝。
如果你熟悉OO編程思想,或原來(lái)有OO設(shè)計(jì)經(jīng)驗(yàn),你可能會(huì)和我相同這樣想,如果一個(gè)數(shù)據(jù)庫(kù)就是個(gè)對(duì)象,所有的操作、信息都通過(guò)方法(Method)、屬性(Attribure)、事件(Event)提供出來(lái),供研發(fā)者使用,那該多好啊。C#正是借助基于這種思想設(shè)計(jì)的數(shù)據(jù)庫(kù)訪問(wèn)技術(shù)ADO.NET,并提供了一系列方便實(shí)用的類(lèi)。應(yīng)用這些數(shù)據(jù)庫(kù)訪問(wèn)的類(lèi),你就能輕松、準(zhǔn)確而且是面向?qū)ο蟮牟倏v數(shù)據(jù)庫(kù)中的各種數(shù)據(jù)了。
如圖,這就是C#中提供的數(shù)據(jù)庫(kù)訪問(wèn)ADO.NET的結(jié)構(gòu)圖?!?

從這張圖中,我們能清晰的了解到ADO.NET的數(shù)據(jù)訪問(wèn)技術(shù)的架構(gòu)。ADO.NET支持SQL Server數(shù)據(jù)訪問(wèn)和OLE DB數(shù)據(jù)訪問(wèn)。兩者相比,前者是針對(duì)SQL Server的數(shù)據(jù)庫(kù)訪問(wèn)引擎,所以訪問(wèn)SQL Server數(shù)據(jù)庫(kù)效率會(huì)高許多,但只支持SQL Server。后者是比較通用的數(shù)據(jù)庫(kù)訪問(wèn)引擎,能支持廣泛的數(shù)據(jù)庫(kù),但效率不如前者。對(duì)研發(fā)者來(lái)說(shuō),如果不用到某種數(shù)據(jù)庫(kù)的特性,其大體使用方法是一致的。
上述內(nèi)容指數(shù)據(jù)庫(kù)的連接部分,也就是上圖中的Connetion對(duì)象。Connection對(duì)象提供了和具體數(shù)據(jù)庫(kù)的連接方式,具體你是用SqlConnection對(duì)象還是OleDbConnection對(duì)象,這個(gè)根據(jù)你的數(shù)據(jù)庫(kù)類(lèi)型由你選擇而定,下面的敘述中,為了不占用過(guò)多的篇幅,在無(wú)特別內(nèi)容的地方,不再分開(kāi)敘述。
下面給出兩段典型的數(shù)據(jù)庫(kù)連接的例子。在此之前,請(qǐng)?jiān)诔淌筋^部using處添加using System.Data.SqlClient或System.Data.OleDb,以確保數(shù)據(jù)庫(kù)訪問(wèn)時(shí)用到的命名空間能引用
- SQL Server數(shù)據(jù)訪問(wèn)
- string strConn="Integrated Security=SSPI;Initial Catalog=MyDatabase;Data Source=YY-POWERPC ";
- SqlConnection myConnection = new SqlConnection (strConn);
- myConnection.Open();
- OleDb數(shù)據(jù)訪問(wèn)
- String strConn="Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=SSPI";
- OleDbConnection myConnection=new OleDbConnection (strConn);
- myConnection.Open();
上述步驟執(zhí)行后,如果沒(méi)有異常拋出,便可成功完成和數(shù)據(jù)庫(kù)的連接。在完成了和數(shù)據(jù)庫(kù)的連接后,接下來(lái)就是建立一個(gè)DataAdapter對(duì)象,來(lái)完成可訪問(wèn)數(shù)據(jù)庫(kù)的工作。DataAdapter的工作是后面DataSet的基礎(chǔ),其內(nèi)容就是建立一個(gè)DataSet和數(shù)據(jù)庫(kù)的中間層,來(lái)協(xié)調(diào)訪問(wèn)。由于DataAdapter和DataSet的關(guān)系十分緊密,我就結(jié)合在一起介紹了。DataAdapter也分為SqlDataAdapter和OleDbDataAdatper兩種。下面給出一段典型代碼(OleDbDataAdapter的情況可類(lèi)推):
- SqlDataAdapter myDataAdapter = new SqlDataAdapter ();
- DataSet myDataSet = new DataSet ();
- string strCom = "SELECT * FROM 會(huì)員信息表";
- myDataAdapter.SelectCommand = new SqlCommand (strCom,myConnection);
- SqlCommandBuilder myCB = new SqlCommandBuilder (myDataAdapter);
- myDataAdapter.Fill (myDataSet,"會(huì)員信息表");
這段代碼用到了SqlDataAdapter、DataSet、SqlCommand、SqlCommandBuilder四個(gè)對(duì)象。從上圖中能看出,SqlDataAdapter的作用就是負(fù)責(zé)和數(shù)據(jù)庫(kù)的通訊訪問(wèn),同時(shí)和DataSet相連,他的內(nèi)部有四個(gè)非常重要的Command對(duì)象(同樣分為SqlCommand和OleDbCommand),都是訪問(wèn)數(shù)據(jù)庫(kù)必用的,分別為SelectCommand、InsertCommand、UpdateCommand、DeleteCommand對(duì)象。這些Command對(duì)象便是專(zhuān)門(mén)用來(lái)完成對(duì)數(shù)據(jù)庫(kù)的查詢(xún)、插入、更新、刪除操作,他們就像四個(gè)大臣,在DataAdapter的控制下分別主管各自的事情。其中SelectCommand是他們四個(gè)中的老大,由他能自動(dòng)的構(gòu)造生成另外的三個(gè)。構(gòu)造生成的過(guò)程就是應(yīng)用CommandBuilder。在這之前,我們只需要指定DataAdapter中的SelectCommand對(duì)象,就能了。
在設(shè)置好了SQL Select語(yǔ)句后,就能開(kāi)始填充相應(yīng)的數(shù)據(jù)集了。方法是應(yīng)用DataAdapter的Fill方法,參數(shù)為DataSet及其中的某個(gè)DataTable。這里要著重講一講DataSet對(duì)象。如果你用過(guò)ADO中的Recordset對(duì)象,你可能會(huì)感覺(jué)到DataSet和Recordset的差別。Recordset一般只能應(yīng)用于單表,即一個(gè)Recordset對(duì)應(yīng)于一張表。而DataSet中有一個(gè)DataTableCollection,即一個(gè)DataTable集合,能包含多個(gè)DataTable對(duì)象。DataTable對(duì)象看上去就更加像一張表了,其中有DataRowCollection、DataColumnCollection、ConstraintCollection。他們分別代表DataRow(數(shù)據(jù)行)、DataColumn(數(shù)據(jù)列)、Constraint(約束關(guān)系)的對(duì)象集合??赡苷f(shuō)這么多,你已有點(diǎn)兒迷糊了,先看一句代碼吧。
- myDataSet.Tables["MyTable"].Rows[3]["MyName"] = "楊揚(yáng)";
怎么樣?是不是一下子就明白了許多。這是一句多么完美的OO思想表達(dá)出的語(yǔ)句啊!這句就是將DataSet下的一個(gè)名為MyTable的"虛表"中的第4行的MyName字段的內(nèi)容改為"楊揚(yáng)"。為什么叫"虛表"呢?這是因?yàn)锳DO.NET的一個(gè)特點(diǎn)就是脫機(jī)連接數(shù)據(jù)庫(kù)。這樣能減少網(wǎng)絡(luò)通訊的壓力,提高效率。你可能會(huì)問(wèn)DataColumn在哪呢?Rows[3]就表示了第4行記錄,換句話說(shuō)Rows[3]就是個(gè)DataRow對(duì)象,一加上["MyName"]就自動(dòng)定位到了MyName字段的內(nèi)容。ADO.NET規(guī)定,訪問(wèn)表中內(nèi)容必須是先行后列的原則,Column["MyName"][3]是不允許的。當(dāng)然,DataColumn也是什么重要的,比如想查看某列的列頭(Field),能用Column[1].ColumnName更改。
好了,目前我覺(jué)得你應(yīng)該大體上明白C#下數(shù)據(jù)庫(kù)編程是怎么一回事了吧,其實(shí)這里只是講了一小部分,因?yàn)锳DO.NET數(shù)據(jù)庫(kù)訪問(wèn)技術(shù)包含的內(nèi)容太多了,不是一兩遍文章就能說(shuō)清的。更有許多許多有用的操作,比如添加、修改、刪除、更新、查詢(xún)等等都還沒(méi)有介紹。
【編輯推薦】