第10章 使用ADO進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)_第1頁(yè)
第10章 使用ADO進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)_第2頁(yè)
第10章 使用ADO進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)_第3頁(yè)
第10章 使用ADO進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)_第4頁(yè)
第10章 使用ADO進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)_第5頁(yè)
已閱讀5頁(yè),還剩227頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第10章使用ADO.NET進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)10.1數(shù)據(jù)庫(kù)概述10.2ADO.NET的基本組件10.3使用ADO.NET10.4綜合案例:圖書(shū)管理系統(tǒng)——使用DataGrid顯示和操作數(shù)據(jù) 本章小結(jié)練習(xí)與作業(yè)上機(jī)部分(十)??學(xué)習(xí)目標(biāo)●解釋ADO.NET●掌握ADO.NET基本組件的使用●掌握基本數(shù)據(jù)庫(kù)編程的步驟和方法10.1數(shù)?據(jù)?庫(kù)?概?述數(shù)據(jù)庫(kù),顧名思義,就是存放數(shù)據(jù)的地方。在計(jì)算機(jī)中,數(shù)據(jù)庫(kù)是數(shù)據(jù)和數(shù)據(jù)庫(kù)對(duì)象的集合。數(shù)據(jù)庫(kù)對(duì)象主要包括表、視圖、存儲(chǔ)過(guò)程、觸發(fā)器等等,要管理數(shù)據(jù)庫(kù)必須使用相應(yīng)的管理系統(tǒng)。數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)就是一套計(jì)算機(jī)應(yīng)用軟件系統(tǒng),主要作用是建立用戶與數(shù)據(jù)庫(kù)之間的信息處理通道,讓用戶能通過(guò)DBMS來(lái)存取和操作數(shù)據(jù)庫(kù)中的數(shù)據(jù),這些數(shù)據(jù)包括建立數(shù)據(jù)庫(kù)、建立表格、添加、更新和刪除數(shù)據(jù)以及查詢(xún)數(shù)據(jù)等。目前通用的數(shù)據(jù)庫(kù)管理系統(tǒng)主要有Access、SQLServer、Oracle、MySQL等。在使用數(shù)據(jù)庫(kù)之前必須要理解一些基本的概念。

1.關(guān)系模型

關(guān)系模型把世界看做是實(shí)體(Entity)和聯(lián)系(Relationship)構(gòu)成的。所謂實(shí)體就是指現(xiàn)實(shí)世界中具有自身獨(dú)有的特征或?qū)傩圆⑴c其他實(shí)體保持聯(lián)系的對(duì)象。在關(guān)系模型中實(shí)體以表的形式來(lái)表現(xiàn),表的每一行描述實(shí)體的一個(gè)實(shí)例,表的每一列描述實(shí)體的一個(gè)特征或?qū)傩?。所謂聯(lián)系就是指實(shí)體之間的關(guān)系或?qū)?yīng)關(guān)系。聯(lián)系可分為三種:一對(duì)一的聯(lián)系。如:一個(gè)學(xué)生只有一個(gè)學(xué)號(hào),姓名→學(xué)號(hào)為一對(duì)一的聯(lián)系。一對(duì)多的聯(lián)系。如:相同班級(jí)的學(xué)生有很多個(gè),班級(jí)→學(xué)號(hào)為一對(duì)多的聯(lián)系。多對(duì)一的聯(lián)系。如:很多學(xué)生有同一個(gè)班級(jí),學(xué)號(hào)→班級(jí)為多對(duì)一的聯(lián)系。通過(guò)聯(lián)系就可以用一個(gè)實(shí)體的信息來(lái)查找另一個(gè)實(shí)體的信息。在圖10-1中,三張表組成了一個(gè)關(guān)系模型,每張表都是一個(gè)實(shí)體。從圖10-1(c)中可看出,最終的結(jié)果依靠?jī)蓮堅(jiān)急淼膶傩躁P(guān)系(如箭頭所示)即學(xué)號(hào)的唯一標(biāo)識(shí)得出。關(guān)系模型能夠得到廣泛使用的原因在于它的靈活性及操作的簡(jiǎn)單。如MicrosoftAccess數(shù)據(jù)庫(kù)、SQLServer數(shù)據(jù)庫(kù)都是基于這種模型。圖10-1關(guān)系模型

2.關(guān)系數(shù)據(jù)庫(kù)對(duì)象

1)表表是數(shù)據(jù)庫(kù)的對(duì)象,表包含數(shù)據(jù)庫(kù)的數(shù)據(jù)。一個(gè)數(shù)據(jù)庫(kù)由一個(gè)或多個(gè)表組成,每個(gè)表存儲(chǔ)一些相關(guān)的數(shù)據(jù)。數(shù)據(jù)庫(kù)中的表與表之間有時(shí)可能存在著關(guān)聯(lián)。表是一個(gè)分別排成行跟列的相關(guān)記錄的集合,類(lèi)似于二維數(shù)組或Excel中的電子表格。數(shù)據(jù)就是以行和列的形式進(jìn)行存儲(chǔ),每個(gè)列表頭就是一個(gè)字段,每一行存儲(chǔ)實(shí)際的數(shù)據(jù)。在設(shè)計(jì)表時(shí)我們可以根據(jù)功能為表創(chuàng)建各種列,如針對(duì)圖10-1所示的學(xué)生信息表,采用Access數(shù)據(jù)庫(kù),設(shè)計(jì)了三列,分別為學(xué)號(hào)、姓名和所屬班級(jí)。請(qǐng)看圖10-2所示學(xué)生信息表的具體結(jié)構(gòu)。圖10-2學(xué)生信息表結(jié)構(gòu)

2)記錄和字段記錄是表示數(shù)據(jù)的集合。記錄在邏輯上相當(dāng)于表的行。例如,學(xué)生信息表的一條記錄可能就包含某個(gè)學(xué)生的信息。記錄是由多個(gè)字段組成的。記錄中的每個(gè)字段都包含了關(guān)于該記錄的單條信息。例如,學(xué)生信息表記錄有學(xué)號(hào)、姓名和所屬班級(jí)等字段。圖10-3對(duì)學(xué)生信息表添加了一些記錄。圖10-3學(xué)生信息表

3)主鍵主鍵唯一標(biāo)識(shí)了表的每一行。主鍵可以是一個(gè)字段,也可以是幾個(gè)字段的組合。對(duì)表中的每一行(記錄)來(lái)說(shuō),主鍵的值都是惟一的。例如,“學(xué)號(hào)”字段是“學(xué)生信息表”的主鍵,因?yàn)槿魏蝺蓚€(gè)學(xué)生的學(xué)號(hào)都不相同。在Access中,可以通過(guò)鼠標(biāo)操作的方式為表添加一個(gè)主鍵,如圖10-4中學(xué)號(hào)上有個(gè)標(biāo)識(shí)。圖10-4具有主鍵的學(xué)生信息表

4)外鍵外鍵是由一個(gè)或者多個(gè)字段組成的,而這些字段又是其他表的主鍵(列)。外鍵描述了表與表之間的關(guān)聯(lián)方式。

5)關(guān)系關(guān)系是建立在兩個(gè)表的公共字段(列)之間的一種關(guān)聯(lián)。關(guān)聯(lián)可以是一對(duì)一、一對(duì)多或者多對(duì)多。關(guān)系使查詢(xún)結(jié)果中可以包括來(lái)自多個(gè)表的數(shù)據(jù)。例如,圖10-5所示的班級(jí)信息表和學(xué)生信息表之間的一對(duì)多關(guān)系將允許查詢(xún)返回相關(guān)專(zhuān)業(yè)的所有學(xué)生。圖10-5表的關(guān)系

3.SQL語(yǔ)言

前面簡(jiǎn)單地介紹了一下數(shù)據(jù)庫(kù)的模型及一些基本的術(shù)語(yǔ),學(xué)到這里不知讀者有沒(méi)有想過(guò),怎么樣才能在一個(gè)程序中把數(shù)據(jù)放進(jìn)數(shù)據(jù)庫(kù)呢?如何得到數(shù)據(jù)庫(kù)的數(shù)據(jù)呢?如何去更新、修改數(shù)據(jù)庫(kù)里面的數(shù)據(jù)呢?……

解決這些問(wèn)題其實(shí)很簡(jiǎn)單,就是利用SQL語(yǔ)言。SQL(StructuredQueryLanguage)全稱(chēng)是“結(jié)構(gòu)化查詢(xún)語(yǔ)言”,是數(shù)據(jù)庫(kù)中使用的標(biāo)準(zhǔn)數(shù)據(jù)查詢(xún)語(yǔ)言。早前美國(guó)ANSI對(duì)SQL進(jìn)行規(guī)范后作為關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)的標(biāo)準(zhǔn)語(yǔ)言,后來(lái)得到國(guó)際標(biāo)準(zhǔn)化組織(ISO)的支持已成為國(guó)際標(biāo)準(zhǔn)。SQL是一種高級(jí)的非過(guò)程化語(yǔ)言,從名稱(chēng)上看,SQL適合于編寫(xiě)查詢(xún)語(yǔ)句,可實(shí)際上它實(shí)現(xiàn)的功能遠(yuǎn)遠(yuǎn)不止于查詢(xún),如創(chuàng)建、刪除、修改、更新等一些對(duì)數(shù)據(jù)庫(kù)的操作都能得心應(yīng)手。接下來(lái)針對(duì)項(xiàng)目中的數(shù)據(jù)表來(lái)編寫(xiě)SQL語(yǔ)句來(lái)實(shí)現(xiàn)對(duì)表數(shù)據(jù)的查找、插入、更新、刪除等操作。1)?Createtable語(yǔ)句Createtable語(yǔ)句用于在數(shù)據(jù)庫(kù)中建立一張新表,包括表的結(jié)構(gòu)。在Access數(shù)據(jù)庫(kù)中,讀者可以使用圖形化界面直接創(chuàng)建及修改。也可以通過(guò)SQL語(yǔ)句靈活實(shí)現(xiàn)。這里只要了解利用語(yǔ)句是如何編寫(xiě)就行了。請(qǐng)看下面對(duì)Createtable語(yǔ)句的定義:Createtable表名(列名1類(lèi)型,列名2類(lèi)型,…,其他參數(shù))

在數(shù)據(jù)庫(kù)中需要?jiǎng)?chuàng)建一個(gè)名稱(chēng)為“學(xué)生成績(jī)表”的表格:Createtable學(xué)生成績(jī)表(學(xué)號(hào)intPRIMARYKEY,姓名char(10),高等數(shù)學(xué)integer,數(shù)據(jù)結(jié)構(gòu)integer,大學(xué)語(yǔ)文integer,體育integer);2)?Altertable語(yǔ)句Altertable語(yǔ)句用于修改表的結(jié)構(gòu),語(yǔ)句定義如下:Altertable表名ALTERCOLUMN列名類(lèi)型|ADD列名類(lèi)型|DROPCOLUMN列名前面創(chuàng)建了一張學(xué)生成績(jī)表,現(xiàn)在用Altertable語(yǔ)句來(lái)修改學(xué)生成績(jī)表的結(jié)構(gòu):Altertable學(xué)生成績(jī)表ADD性別char(2);Altertable學(xué)生成績(jī)表ALTERCOLUMN姓名char(8);

說(shuō)明:在上面的兩個(gè)范例中,利用Altertable語(yǔ)句向?qū)W生成績(jī)表中添加一個(gè)名為“性別”的列,并把學(xué)生成績(jī)表名為“姓名”的列的數(shù)據(jù)類(lèi)型大小改為8。3)?INSERTINTO語(yǔ)句前面利用Createtable語(yǔ)句為學(xué)生信息管理項(xiàng)目創(chuàng)建了表的結(jié)構(gòu),現(xiàn)在還需要往表里存放數(shù)據(jù)、讀取數(shù)據(jù)及修改數(shù)據(jù)等操作。INSERTINTO命令語(yǔ)句就是用來(lái)向表中的列插入值。INSERTINTO語(yǔ)句定義如下:INSERTINTO表名(列名1,列名2,…)VALUES(常量1,常量2,…)其中(列名1,列名2,…)可省略。例句:INSERTINTO學(xué)生成績(jī)表VALUES(0001,'李明',88.5,69,75,90);

學(xué)號(hào)姓名高等數(shù)學(xué)……

說(shuō)明:在上述例句中,利用INSERTINTO語(yǔ)句向?qū)W生成績(jī)表的各列都插了值,現(xiàn)表中已有一行值。注:括號(hào)后面的值應(yīng)該跟所定義表的結(jié)構(gòu)的順序一致。如果表的結(jié)構(gòu)中有定義字符的數(shù)據(jù)類(lèi)型,應(yīng)使用單引號(hào)。4)?UPDATE語(yǔ)句利用UPDATE命令語(yǔ)句可用于更新表中的數(shù)據(jù)。定義如下:

UPDATE表名SET字段=值,字段=值,…WHERE條件語(yǔ)句例句1:UPDATE學(xué)生成績(jī)表SET體育=85WHERE學(xué)號(hào)=0001;例句2:UPDATE學(xué)生成績(jī)表SET體育=85;

說(shuō)明:在上面的兩個(gè)例句中,利用UPDATE語(yǔ)句對(duì)學(xué)生成績(jī)表進(jìn)行更新。例句1把學(xué)生成績(jī)表的學(xué)號(hào)為0001的學(xué)生的體育成績(jī)更改為85分。例句2把學(xué)生成績(jī)表的每位學(xué)生的體育成績(jī)都更改為85分。不使用WHERE子句UPDATE命令將更新表中的所有行。5)?DELETE語(yǔ)句利用Delete語(yǔ)句可用于刪除表的記錄。定義如下:

DELETEFROM表名WHERE條件語(yǔ)句請(qǐng)看范例:DELETEFROM學(xué)生成績(jī)表WHERE學(xué)號(hào)=03002;解釋?zhuān)豪肈ELETE語(yǔ)句把學(xué)生成績(jī)表的學(xué)號(hào)為03002的學(xué)生的記錄刪除。6)?SELECT語(yǔ)句對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)進(jìn)行查詢(xún)是SQL語(yǔ)言的核心部分,語(yǔ)句的一般格式為:SELECT目標(biāo)列FROM表名WHERE條件語(yǔ)句GROUPBY列名1HAVING內(nèi)部函數(shù)表達(dá)式ORDERBY列名2ASC/DESC例句(1):SELECT學(xué)號(hào)FROM學(xué)生成績(jī)表;說(shuō)明:使用SELECT語(yǔ)句查找學(xué)生成績(jī)表的所有學(xué)號(hào)的值。例句(2):SELECT學(xué)號(hào),姓名From學(xué)生成績(jī)表;說(shuō)明:使用SELECT語(yǔ)句查找學(xué)生成績(jī)表的所有學(xué)號(hào)、姓名的值。例句(3):SELECT*FROM學(xué)生成績(jī)表;說(shuō)明:使用SELECT語(yǔ)句查找學(xué)生成績(jī)表的所有記錄,即學(xué)生成績(jī)表中的所有行?!?”代表所有列。接下來(lái)用限定詞、通配符、函數(shù)及操作數(shù)等來(lái)對(duì)SELECT語(yǔ)句進(jìn)一步擴(kuò)充?!裢ㄅ浞c多重條件查詢(xún)通配符使用LIKE或NOTLIKE操作數(shù)進(jìn)行模糊條件查詢(xún),以判斷列值是否與指定的字符串格式相匹配。常用通配符如表10-1所示。表10-1常用通配符例句(4):SELECT*FROM學(xué)生成績(jī)表WHERE姓名LILE'J%';說(shuō)明:使用SELECT語(yǔ)句查詢(xún)學(xué)生成績(jī)表所有列值首字符為“J”的值。上面的插入、更新、刪除、查找命令為SQL語(yǔ)句最為基礎(chǔ)也是最常用的命令,事實(shí)上在一般項(xiàng)目中用得多的就是SELECT語(yǔ)句命令了,而其他的的插入、更新等命令則不必編寫(xiě),因?yàn)榭梢越柚鶤DO.NET技術(shù)的CommandBuilder對(duì)象自動(dòng)生成。如果讀者有興趣的話可以再進(jìn)一步學(xué)習(xí)有關(guān)SQL語(yǔ)句命令的擴(kuò)充。7)?DROP、DELETE、TRUNCATETABLF語(yǔ)句的區(qū)別DROP、DELETE、TRUNCATETABLE語(yǔ)句都為刪除命令語(yǔ)句,但它們之間的使用是有區(qū)別的。DROP語(yǔ)句用于刪除整個(gè)表格,即刪除表的數(shù)據(jù)跟表結(jié)構(gòu);DELETE語(yǔ)句用于有選擇地刪除表中的行值;TRUNCATETABLE語(yǔ)句用于刪除整個(gè)表所有行的值,但不刪除表結(jié)構(gòu)。語(yǔ)法定義如下:DROPTABLE表名;DELETEFROM表名WHERE條件語(yǔ)句;TRUNCATEtable表名;

下面通過(guò)一些SQL語(yǔ)句示例實(shí)現(xiàn)對(duì)表中數(shù)據(jù)進(jìn)行操作。先創(chuàng)建一個(gè)名STUDENT的表,并向表插入三行值(利用CREATETABLE、INSERTINTO語(yǔ)句)。CreatetableSTUDENT(學(xué)號(hào)int,姓名char(8),年齡int);INSERTINTOSTUDENTVALUES(03001,'張三',20);INSERTINTOSTUDENTVALUES(03002,'李四',21);INSERTINTOSTUDENTVALUES(03003,'王五',23);例句(1):DELETEFROMSTUDENTWHERE學(xué)號(hào)=03002;說(shuō)明:刪除STUDENT表中學(xué)號(hào)為03002學(xué)生的記錄。例句(2):TRUNCATETABLESTUDENT;說(shuō)明:刪除STUENDT表的所有行,即表中的所有學(xué)生信息全部刪除。例句(3):DROPTABLESTUDENT;說(shuō)明:刪除STUDENT表。注意:DROPTABLEI不能刪除有外鍵約束引用的表,必須先將外鍵約束刪除。TRUNCATETABLE同樣不能用于有外鍵約束引用的表,在這種情況下,就要用到不帶WHERE子句的DELETE語(yǔ)句了。

8)使用AND、OR、NOT關(guān)鍵字進(jìn)行多重條件查詢(xún)例句:

SELECT姓名FROMSTUDENTWHERE學(xué)號(hào)=03003AND年齡=22; 說(shuō)明:查詢(xún)STUDENT表中列為姓名的學(xué)號(hào)為03003且年齡為22的值。注意:在運(yùn)算過(guò)程中NOT優(yōu)先級(jí)最高,次之AND最后為OR,但可通過(guò)加括號(hào)來(lái)改變。

9)使用ALL、DISTINCT、TCOP限定詞TOP關(guān)鍵字用來(lái)限制顯示查詢(xún)返回得到的行數(shù)。例句(1):SELECTTOP2*FROMSTUDENT;

說(shuō)明:查詢(xún)STUDENT表的所有行且只顯示前兩行。ALL關(guān)鍵字用來(lái)顯示查詢(xún)返回得到的所有行(包括重復(fù)的行)。例句(2):SELECTALL學(xué)號(hào)FROMSTUDENT;說(shuō)明:查詢(xún)STUDENT表的學(xué)號(hào)字段所有行的值。DISTINCT關(guān)鍵字用來(lái)刪除查詢(xún)得到的重復(fù)值的行。例句(3):SELECTDISTINCT學(xué)號(hào)FROMSTUDENT;說(shuō)明:查詢(xún)STUDENTG表的學(xué)號(hào)字段不重復(fù)值的所有行的值。

10)使用[NOT]Between…AND…與IN關(guān)鍵字Between…AND…用于查找字段值在或者不在指定范圍內(nèi)的值。例句(1):SELECT*FROMSTUDENTWHERE年齡Between20AND23;說(shuō)明:查詢(xún)?cè)赟TUDENT表中年齡介于20~23之間的所有行。例句(2):SELECT*FROMSTUDENTWHERE年齡NOTBetween20AND23;說(shuō)明:查詢(xún)?cè)赟TUDENT表中年齡不介于20~23之間的所有行。IN關(guān)鍵字用來(lái)查找字段值屬于在指定集合的范圍內(nèi)的值。例句(3):SELECT*FROMSTUDENTWHERE學(xué)號(hào)in('03001','03003');說(shuō)明:查詢(xún)?cè)赟TUDENT表中學(xué)號(hào)為03001跟03003的所有行。

11)使用集合函數(shù)

集合函數(shù)用于統(tǒng)計(jì)個(gè)數(shù)及計(jì)算數(shù)值,功能如表10-2所示。表10-2常用集合函數(shù)表說(shuō)明:ALL與DISTINCT是可選項(xiàng),ALL計(jì)算時(shí)忽略重復(fù),DISTINCT則不重復(fù)。COUNT(*)會(huì)返回所有行包括值為空(NULL)的記錄行數(shù),COUNT(field)則不返回值為空的記錄行數(shù)。例句:SELECTCOUNT(姓名)FROM學(xué)生成績(jī)表WHERE高等數(shù)學(xué)>80;

說(shuō)明:查詢(xún)學(xué)生成績(jī)表中高等數(shù)學(xué)80分以上的學(xué)生的姓名。

12)使用ORDERBY、GROUPBY、HAVING子句OREDERBY子句用于對(duì)查詢(xún)所得行進(jìn)行排序,關(guān)鍵字ASC為升序,DESC為降序,默認(rèn)則為升序排序;GROUPBY子句用于對(duì)查詢(xún)所得行按某一列或多列值進(jìn)行分組顯示,值相等的則為同一組;HAVING子句則用于在使用GROUPBY子句進(jìn)行分組后對(duì)行進(jìn)行判斷篩選。例句(1):SELECT*FROMSTUDENTORDERBY年齡DESC;說(shuō)明:查詢(xún)STUDENT表的所有記錄并以年齡字段顯示為降序排序。例句(2):SELECT姓名FROM學(xué)生成績(jī)表GROUPBY學(xué)號(hào)HAVING高等數(shù)學(xué)>60;說(shuō)明:查詢(xún)STUDENT表中高等數(shù)學(xué)分?jǐn)?shù)60分以上的學(xué)生的姓名,并以學(xué)號(hào)字段進(jìn)行分組顯示。

注意:HAVING子句應(yīng)始終在GROUPBY子句之后使用。上面所講的SQL語(yǔ)法只是一些比較簡(jiǎn)單、常用的語(yǔ)句。如果讀者想再對(duì)SQL語(yǔ)言進(jìn)一步深入學(xué)習(xí)、探索的話,應(yīng)該看一些其他關(guān)于SQL方面的書(shū)籍,如SQLSERVER等。10.2ADO.NET的基本組件無(wú)論需要怎樣使用數(shù)據(jù),都應(yīng)該理解ADO.NET中數(shù)據(jù)方法的一些基本概念。你也許永遠(yuǎn)不需要知道數(shù)據(jù)處理的一些細(xì)節(jié),但是理解ADO.NET中的數(shù)據(jù)結(jié)構(gòu)和主要數(shù)據(jù)組件,以及理解各部分如何組合到一起,都會(huì)對(duì)你有所幫助。本節(jié)并不講述詳盡的細(xì)節(jié),而是介紹ADO.NET中與數(shù)據(jù)集成相關(guān)的概念。1.定義ADO.NET是.NETFramework架構(gòu)中一組用于數(shù)據(jù)操作的類(lèi)。它提供了為非連接環(huán)境設(shè)計(jì)的系統(tǒng)、高級(jí)XML支持的編程模型和在Microsoft.NET框架內(nèi)用于數(shù)據(jù)訪問(wèn)的類(lèi)、接口、結(jié)構(gòu)和枚舉類(lèi)型。ADO.NET組件主要分為兩大類(lèi):(1)數(shù)據(jù)存?。篋ataSet類(lèi),獨(dú)立于不同數(shù)據(jù)源的數(shù)據(jù)存取服務(wù)組件。(2)數(shù)據(jù)操作:.NETFrameworkDataProvider和NETFramework的數(shù)據(jù)提供者,包含有四個(gè)核心組件:Connection對(duì)象、Command對(duì)象、DataReader對(duì)象和DataAdapter對(duì)象。利用微軟官方發(fā)布的ADO.NET架構(gòu)圖(如圖10-6),可以讓我們更清楚地了解上述兩大類(lèi)組件之間的關(guān)系。圖10-6ADO.NET架構(gòu)圖2.ADO.NET對(duì)象概述ADO.NET中Connection對(duì)象建立到數(shù)據(jù)源的連接。它有ConnectionString屬性、Open和Close方法以及使用BeginTransaction方法開(kāi)始事務(wù)處理的能力。Command對(duì)象允許你查詢(xún)數(shù)據(jù)庫(kù)、向它發(fā)送命令或者調(diào)用它的存儲(chǔ)過(guò)程??梢允褂迷搶?duì)象的某個(gè)Executexxx方法來(lái)執(zhí)行這些操作。例如,使用ExecuteNonQuery方法向數(shù)據(jù)庫(kù)發(fā)送操作查詢(xún)(比如INSERT或DELETESQL語(yǔ)句),并使用ExecuteReader方法執(zhí)行會(huì)返回結(jié)果集的SELECT查詢(xún)。其他屬性允許你設(shè)置命令超時(shí)或?yàn)檎{(diào)用存儲(chǔ)過(guò)程設(shè)置參數(shù)。你必須手動(dòng)地把Command對(duì)象和先前已經(jīng)連接到數(shù)據(jù)源的Connection對(duì)象相關(guān)聯(lián)。DataReader對(duì)象是Command對(duì)象的ExecuteReader方法返回的對(duì)象,它代表只向前的、只讀的結(jié)果集。每次調(diào)用DataReader的Read方法時(shí)都會(huì)產(chǎn)生一行新的可用結(jié)果,然后,就可以使用GetValue方法或者某個(gè)強(qiáng)制類(lèi)型的Getxxx方法(比如GetString或GetFloat)查詢(xún)每個(gè)單獨(dú)的字段。記住,不能使用DataReader對(duì)象更新數(shù)據(jù)庫(kù)。DataAdapte對(duì)象起著Connection對(duì)象和DataSet對(duì)象之間的橋梁作用。其Fill方法將數(shù)據(jù)從數(shù)據(jù)庫(kù)移到客戶端的DataSet對(duì)象,而其Update方法則按相反方向移動(dòng)數(shù)據(jù),它使用由應(yīng)用程序在DataSet中添加、更改或刪除的行對(duì)數(shù)據(jù)庫(kù)進(jìn)行更新。DataSet對(duì)象是ADO.NET非連接架構(gòu)下的主要對(duì)象。它在使用時(shí)就像駐留在客戶端計(jì)算機(jī)上的一個(gè)小型關(guān)系數(shù)據(jù)庫(kù),但又與任何具體的數(shù)據(jù)庫(kù)完全無(wú)關(guān)。它包含一個(gè)DataTable對(duì)象的集合,其中每個(gè)DataTable對(duì)象都包含一個(gè)不同的結(jié)果集(通常情況下,它是對(duì)不同數(shù)據(jù)庫(kù)表的查詢(xún)結(jié)果)。DataTable對(duì)象包含一個(gè)DataRow對(duì)象的集合,而每個(gè)DataRow對(duì)象則包含了結(jié)果集里不同行中的數(shù)據(jù)。DataSet還包含一個(gè)DataRelation對(duì)象的集合,其中每一項(xiàng)都對(duì)應(yīng)一個(gè)不同DataTable對(duì)象之間的關(guān)系,這很像關(guān)系數(shù)據(jù)庫(kù)中表與表之間的關(guān)系。這些關(guān)系允許你使用簡(jiǎn)單而又很有效的語(yǔ)法編寫(xiě)代碼,從而實(shí)現(xiàn)同一DataSet中表與表之間的導(dǎo)航。.NET框架包括許多?.NETDataProvider,例如SQL

Server.NETDataProvider,OLEDB.NETDataProviderforSQL和OLEDBProviderforMicrosoftJet等。你也可以為任意數(shù)據(jù)源編寫(xiě)自定義的.NETDataProvider。3.ADO.NET組件的命名空間結(jié)構(gòu)ADO.NET中常用的NETFramework數(shù)據(jù)提供組件有兩種,分別是SQLServer數(shù)據(jù)提供組件和OLEDB數(shù)據(jù)提供組件。前者支持SQLServer7.0或更高版本,直接與SQLServer底層API溝通,性能較高。它屬于System.Data.SqlClient命名空間。OLEDB數(shù)據(jù)提供組件用于訪問(wèn)如Access、Oracle等數(shù)據(jù)源。當(dāng)然OLEDB組件也可以用于訪問(wèn)SQLServer數(shù)據(jù)源,但由于有中間層的加入,性能不是很好。該組件屬于System.Data.OleDb命名空間。上面兩種數(shù)據(jù)提供組件,都實(shí)現(xiàn)了Connection對(duì)象、Command對(duì)象、DataReader對(duì)象和DataAdapter對(duì)象的模型,如表10-3所示。此外,我們還將使用到System.Data命名空間,它也是.NETFramework用來(lái)存取數(shù)據(jù)的主要組件。表10-4介紹了System.Data的幾個(gè)常見(jiàn)的子類(lèi)。各個(gè)子類(lèi)的關(guān)系如圖10-7所示。表10-3兩種數(shù)據(jù)提供組件中的對(duì)象表10-4System.Data的幾個(gè)常見(jiàn)的子類(lèi)圖10-7System.Data中各個(gè)子類(lèi)的關(guān)系使用VisualStudio2005創(chuàng)建程序時(shí),系統(tǒng)將默認(rèn)應(yīng)用System.Data.dll組件。因此,不需要再添加對(duì)System.Data的引用,直接在程序中使用using把命名空間導(dǎo)入即可。如果要引用該組件,請(qǐng)?jiān)陧?xiàng)目的引用上單擊,添加相應(yīng)的組件,如圖10-8所示。

注意:組件,也叫程序集,是命名空間的物理表示。如果要使用usingSystem.Data;語(yǔ)句,必須先將System.dll組件添加進(jìn)來(lái)。直接在項(xiàng)目中輸入using語(yǔ)句是無(wú)效的。圖10-8添加程序集引用10.3使用ADO.NET開(kāi)發(fā)應(yīng)用程序時(shí),可能需要通過(guò)不同的方式使用數(shù)據(jù),有時(shí)只希望數(shù)據(jù)顯示在窗體上,而有時(shí)需要設(shè)計(jì)一種方法來(lái)與其他組織共享信息。使用數(shù)據(jù)時(shí),可以使用各種對(duì)象來(lái)檢索和修改數(shù)據(jù)庫(kù)中的信息。一般來(lái)說(shuō),要在ADO.NET中使用數(shù)據(jù)庫(kù),需要執(zhí)行下列步驟:(1)連接到數(shù)據(jù)庫(kù)。(2)請(qǐng)求特定的數(shù)據(jù)。確定想要檢索的數(shù)據(jù)以及需要對(duì)它進(jìn)行訪問(wèn)的方式是只讀訪問(wèn)還是讀/寫(xiě)訪問(wèn)。(3)檢索并顯示數(shù)據(jù)。(4)關(guān)閉連接(在某些應(yīng)用程序中)。(5)修改檢索得到的數(shù)據(jù)(如果有讀/寫(xiě)訪問(wèn)權(quán)限)。(6)重新打開(kāi)連接(在某些應(yīng)用程序中)。(7)將對(duì)數(shù)據(jù)所做的所有更改都傳回?cái)?shù)據(jù)庫(kù)。(8)關(guān)閉連接。在上述過(guò)程中,必須采用ADO.NET中用于連接數(shù)據(jù)源和使用數(shù)據(jù)的所有必要組件。在本節(jié)里,將學(xué)習(xí)這些組件對(duì)象的創(chuàng)建和設(shè)置,以及如何使用這些對(duì)象連接到數(shù)據(jù)庫(kù)、檢索數(shù)據(jù)、修改數(shù)據(jù)以及如何將更新后的數(shù)據(jù)傳回?cái)?shù)據(jù)庫(kù)。10.3.1使用Connection對(duì)象無(wú)論是在連接模式還是非連接模式下工作,在使用數(shù)據(jù)源時(shí),需要執(zhí)行的第一步都是打開(kāi)到數(shù)據(jù)源的連接。用ADO.NET術(shù)語(yǔ),這就意味著創(chuàng)建一個(gè)到指定數(shù)據(jù)庫(kù)的Connection對(duì)象。1.選擇Connection對(duì)象可以使用Connection對(duì)象來(lái)連接特定的數(shù)據(jù)源。既可以使用SqlConnection連接到SQLServer數(shù)據(jù)庫(kù),也可以使用OleDbConnection連接到其他類(lèi)型的數(shù)據(jù)源。這里要注意的是,SqlConnection和OleDbConnection位于不同的命名空間下,分別為System.Data.OleDb和System.Data.SqlClient,使用時(shí)請(qǐng)先將其導(dǎo)入。表10-5和表10-6分別說(shuō)明了兩種Connection對(duì)象的屬性和方法。表10-5SqlConnection屬性和方法表10-6OleDbConnection的屬性和方法2.指定數(shù)據(jù)源在選擇了連接對(duì)象類(lèi)型之后,可以使用Connection對(duì)象ConnectionString屬性來(lái)指定DataProvider、數(shù)據(jù)源和其他用于建立連接的信息。連接字符串的格式在SqlClient命名空間和OleDb命名空間之間稍有不同。3.設(shè)置ConnectionString屬性ConnectionString是Connection對(duì)象的關(guān)鍵屬性,它是一個(gè)字符串,用于定義正在連接的數(shù)據(jù)庫(kù)的類(lèi)型、位置以及其他屬性,這些屬性用分號(hào)分隔。通常情況下,該字符串包含如下信息:(1)?Provider特性:它指定用于連接到數(shù)據(jù)的OLEDBProvider的名稱(chēng)。在書(shū)寫(xiě)時(shí),所有合法的值包括SQLOLEDB(MicrosoftSQLServer的OLEDBProvider)、Microsoft.Jet.OLEDB.4.0(MicrosoftAccess的OLEDBProvider)和MSDAORA(Oracle的OLEDBProvider)。(2)?DataSource特性:它指定數(shù)據(jù)庫(kù)的位置,既可以是Access數(shù)據(jù)庫(kù)的路徑,也可以是SQLServer或Oracle數(shù)據(jù)庫(kù)所在計(jì)算機(jī)的名稱(chēng)。(3)?UserID和Password特性:它們指定用戶名和該數(shù)據(jù)庫(kù)的有效帳戶密碼。(4)?InitialCatalog特性:當(dāng)連接到SQLServer或Oracle數(shù)據(jù)源時(shí),它指定數(shù)據(jù)庫(kù)的名稱(chēng)。(5)?IntegratedSecurity特性:SQLServer的整合安全性。若為T(mén)rue,則用Windows帳戶進(jìn)行驗(yàn)證;若為False,則需要在連接時(shí)指定用戶名和密碼。一旦正確設(shè)置了ConnectionString,就可以通過(guò)調(diào)用Open方法打開(kāi)連接:stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+ "DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection();cn.ConnectionString=constr;cn.Open(); //打開(kāi)db1數(shù)據(jù)庫(kù)通過(guò)將連接字符串傳遞給Connection對(duì)象的構(gòu)造函數(shù),可以使代碼更為簡(jiǎn)潔:OleDbConnectioncn=newOleDbConnection(constr);cn.Open(); //更簡(jiǎn)潔的方式打開(kāi)db1數(shù)據(jù)庫(kù)以上描述同樣可以用于SqlConnection對(duì)象,其中只有一個(gè)區(qū)別:不能包括連接字符串的Provider特性。實(shí)際上,在這種情況下根本就不需要該特性,因?yàn)槭褂肧QLServer.NETDataProvider時(shí),只能連接到SQLServer數(shù)據(jù)庫(kù)。另一個(gè)要注意的地方是如果連接到本地計(jì)算機(jī)上的SQLServer,可以將DataSource特性指定為(local):stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs";SqlConnectioncn=newSqlConnection(constr);cn.Open();該連接字符串可以包括一些其他特性。例如,ConnectionTimeout特性用來(lái)設(shè)置連接嘗試能夠等待的時(shí)間(缺省值為15秒),如在這段時(shí)間內(nèi)無(wú)法連接,將返回錯(cuò)誤。打開(kāi)連接之后,可以用ConnectionTimeout屬性查詢(xún)?cè)摮瑫r(shí)時(shí)段長(zhǎng)度://指定一個(gè)更長(zhǎng)的連接到Pubs時(shí)的超時(shí)時(shí)段。stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs;ConnectionTimeout=30";SqlConnectioncn=newSqlConnection(constr);cn.Open();Debug.Write(cn.ConnectionTimeout); //在輸出窗口顯示30是否要在連接字符串中傳遞其他值,取決于連接所使用的特定OLEDBProvider。例如,Microsoft.Jet.OLEDB.4.0的Provider支持設(shè)置數(shù)據(jù)庫(kù)密碼,也支持包含有關(guān)組和用戶信息的系統(tǒng)數(shù)據(jù)庫(kù)。使用SQLServer.NETDataProvider,可以在連接字符串中指定其他兩個(gè)屬性:PacketSize和WorkstationID。前者用來(lái)設(shè)置網(wǎng)絡(luò)數(shù)據(jù)包(該數(shù)據(jù)包用于與SQLServer通信)的大?。缓笳呖梢杂糜跇?biāo)識(shí)客戶端。有時(shí),PacketSize屬性對(duì)于優(yōu)化應(yīng)用程序與SQLServer之間的數(shù)據(jù)流量很有用處。例如,如果處理大的BLOB字段(比如圖像),那么可以設(shè)置一個(gè)較大的值;如果經(jīng)常對(duì)服務(wù)器作小數(shù)據(jù)量的查詢(xún),那么可以設(shè)置一個(gè)較小的值。//優(yōu)化對(duì)BLOB的連接。stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs;PacketSize=32767";SqlConnectioncn=newSqlConnection(constr);cn.Open();Debug.Write(cn.PacketSize); //在輸出窗口顯示327674.打開(kāi)和關(guān)閉連接如前所述,Open方法和Close方法不帶參數(shù):OleDbConnectioncn=newOleDbConnection(constr);cn.Open();//執(zhí)行數(shù)據(jù)庫(kù)操作cn.Close();●?State屬性和StateChange事件(1)?State屬性是一個(gè)按位編碼的字段,指示數(shù)據(jù)庫(kù)連接的當(dāng)前狀態(tài)。它可以是下列ConnectionState枚舉值中一個(gè)或者多個(gè)值的組合:Closed、Connecting、Open、Executing、Fetching和Broken。通常情況下,需檢查State屬性以確保打開(kāi)一個(gè)關(guān)閉著的連接或者關(guān)閉一個(gè)已打開(kāi)的連接,如下列代碼所示://如果連接已打開(kāi),關(guān)閉該連接if(cn.State==ConnectionState.Open) cn.Close();;需要注意的是,當(dāng)連接不再需要時(shí),應(yīng)該及時(shí)把它關(guān)閉,以免占用過(guò)多的數(shù)據(jù)庫(kù)連接資源。(2)StateChange事件是當(dāng)State屬性發(fā)生改變時(shí)觸發(fā)的,經(jīng)常用在“當(dāng)數(shù)據(jù)庫(kù)連接對(duì)象的連接狀態(tài)發(fā)生改變時(shí)”,可以對(duì)連接對(duì)象進(jìn)行及時(shí)處理。

【例10-1】使用控制臺(tái)程序建立對(duì)SQLServer的連接。usingSystem;usingSystem.Data.SqlClient;usingSystem.Data;classTestConnection{staticvoidMain(){SqlConnectioncn=newSqlConnection();//創(chuàng)建一個(gè)連接對(duì)象try{stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=NorthWind";cn.ConnectionString=constr; //設(shè)置連接字符串cn.Open();Console.WriteLine("連接已打開(kāi)");}catch(SqlExceptione){Console.WriteLine(e.Message);}finally{if(cn.State!=ConnectionState.Closed)//判斷連接狀態(tài){cn.Close();Console.WriteLine("連接已關(guān)閉");}}}}程序的運(yùn)行效果如圖10-9所示。圖10-9運(yùn)行結(jié)果10.3.2使用Command對(duì)象在打開(kāi)了連接之后,你可以決定是在連接環(huán)境還是非連接環(huán)境下工作。對(duì)前一種情況,通常可以創(chuàng)建一個(gè)Command對(duì)象,該對(duì)象包含一個(gè)選擇查詢(xún)(從數(shù)據(jù)庫(kù)讀取數(shù)據(jù))或者一個(gè)操作查詢(xún)(更新數(shù)據(jù)),然后執(zhí)行Executexxx方法(確切的名稱(chēng)取決于查詢(xún)的類(lèi)型)。Command對(duì)象按數(shù)據(jù)庫(kù)類(lèi)型也分為兩大類(lèi):SqlCommand用于執(zhí)行SQLServer中的命令,OleDbCommand對(duì)象用于執(zhí)行非SQLServer數(shù)據(jù)庫(kù)中的命令。表10-7和表10-8分別說(shuō)明了兩種Command對(duì)象的屬性和方法。表10-7SqlCommand的屬性和方法表10-8OleDbCommand的屬性的方法1.創(chuàng)建Command對(duì)象對(duì)象的關(guān)鍵屬性是CommandText(執(zhí)行操作查詢(xún)或選擇查詢(xún)的SQL文本)和Connection(查詢(xún)所基于的連接)。你可以逐個(gè)設(shè)置這些屬性,如下列代碼所示://創(chuàng)建和打開(kāi)連接stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+"DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);cn.Open();//設(shè)置執(zhí)行字符串stringsqlstr="insertintoStudent(stuid,name)values(5,'mike')";OleDbCommandcmd=newOleDbCommand();cmd.Connection=cn;cmd.CommandText=sqlstr;//執(zhí)行語(yǔ)句,返回被影響的行數(shù)intrecords=cmd.ExecuteNonQuery();Debug.Write(records); //輸出1//關(guān)閉連接cn.Close();也可以將這兩個(gè)值傳遞給Command對(duì)象的構(gòu)造方法,這樣代碼更簡(jiǎn)潔:OleDbCommandcmd=newOleDbCommand(sqlstr,cn);2.發(fā)出數(shù)據(jù)庫(kù)命令正如在前面的代碼中所看到的,使用ExecuteNonQuery方法(它返回受到該語(yǔ)句影響的記錄的數(shù)目),可以通過(guò)Command對(duì)象來(lái)執(zhí)行插入、更新和刪除操作:stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+ "DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);cn.Open();//設(shè)置執(zhí)行字符串,刪除一條記錄stringsqlstr="deletefromStudentwherestuid=5";OleDbCommandcmd=newOleDbCommand(sqlstr,cn);intrecords=cmd.ExecuteNonQuery();Debug.Write(records); //輸出1cn.Close();當(dāng)然,從安全及排錯(cuò)的角度來(lái)說(shuō),應(yīng)該將它(以及所有的數(shù)據(jù)庫(kù)操作)放在try代碼塊中保護(hù)起來(lái):try{ //運(yùn)行查詢(xún);獲取受影響記錄的數(shù)目 intrecords=cmd.ExecuteNonQuery();}catch{ //在這里處理錯(cuò)誤 ...}finally{ //總是關(guān)閉連接 cn.Close();}【例10-2】使用Windows程序操作SQLServer數(shù)據(jù)庫(kù),步驟如下:(1)首先創(chuàng)建一個(gè)WinForm程序,對(duì)窗體Form1的設(shè)計(jì)界面如圖10-10所示。圖10-10設(shè)計(jì)界面(2)導(dǎo)入所需的命名空間,然后在代碼區(qū)定義成員變量及方法。SqlConnectioncn=newSqlConnection("DataSource=(local);UserID=sa;Password=41919;InitialCatalog=northwind");SqlCommandcmd=newSqlCommand();privateboolcheckSame(stringbh) //判斷輸入的客戶號(hào)是否重復(fù){cmd.Connection=cn;cmd.CommandText="selectcount(*)fromcustomerswherecustomerid='"+bh+"'";if(cmd.ExecuteScalar().ToString()=="0")returntrue;elsereturnfalse;}(3)在【添加記錄】按鈕的Click事件中添加如下代碼:privatevoidbutton1_Click(objectsender,EventArgse){stringkhh,gsm,xm;khh=textBox1.Text;gsm=textBox2.Text;xm=textBox3.Text;try{if(cn.State==ConnectionState.Closed)cn.Open();if(checkSame(khh)==false{MessageBox.Show("存在相同的客戶號(hào),請(qǐng)重新輸入!");textBox1.Focus();}else{cmd.CommandText="insertintocustomers(customerid,companyname,contactname)values('"+khh+"','"+gsm+"','"+xm+"')";cmd.Connection=cn;cmd.ExecuteNonQuery(); //執(zhí)行添加操作MessageBox.Show("記錄已成功添加!");}}catch(SqlExceptionex){MessageBox.Show(ex.Message);}finally{cn.Close();}}(4)保存并運(yùn)行程序,結(jié)果如圖10-11所示。圖10-11運(yùn)行結(jié)果10.3.3使用DataReader對(duì)象此對(duì)象用于從數(shù)據(jù)源中獲取只讀和只進(jìn)數(shù)據(jù)。DataReader在任何時(shí)候都只在內(nèi)存中保存一行數(shù)據(jù),減少了內(nèi)存開(kāi)銷(xiāo),提高了性能。和Connection對(duì)象一樣,DataReader對(duì)象也包含兩種類(lèi)型:SqlDataReader和OleDbDataReader。表10-9和表10-10分別說(shuō)明了兩種DataReader對(duì)象的屬性和方法。使用DataReader對(duì)象也很簡(jiǎn)單:調(diào)用它的Read方法前進(jìn)到數(shù)據(jù)集的下一行,并檢查其返回值。如果返回值為false,則已經(jīng)到了數(shù)據(jù)集的末端;如果返回值為true,則還有更多的記錄。根據(jù)這個(gè)布爾函數(shù),可以使用DataReader對(duì)象建立循環(huán)://創(chuàng)建和打開(kāi)連接stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+ "DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);cn.Open();//設(shè)置執(zhí)行字符串stringsqlstr="selectstuidfromStudent";OleDbCommandcmd=newOleDbCommand(sqlstr,cn);OleDbDataReaderdr=cmd.ExecuteReader();while(dr.Read()) //循環(huán)讀取DataReader中的每一條記錄{Debug.WriteLine("stuid:"+dr.GetInt16(0));}//關(guān)閉連接cn.Close();表10-9SqlDataReader的屬性和方法表10-10OleDbtaReader的屬性和方法當(dāng)不必再對(duì)行進(jìn)行處理的時(shí)候,一定要關(guān)閉DataReader對(duì)象。這樣可以釋放客戶端計(jì)算機(jī)和服務(wù)器上的資源,并使得該連接可以再度為其他命令所用。實(shí)際上,當(dāng)連接上有激活的DataReader對(duì)象時(shí),你就不能在該連接上發(fā)出任何其他命令。DataReader在使用一個(gè)連接時(shí),在該連接上惟一可以執(zhí)行的命令就是Close方法??梢酝ㄟ^(guò)連接的State屬性檢查它是否可用。DataReader對(duì)象沒(méi)有這種屬性,不過(guò)可以通過(guò)它的IsClosed屬性來(lái)檢查它是否已經(jīng)關(guān)閉?!纠?0-3】使用Windows程序顯示數(shù)據(jù),步驟如下:(1)首先創(chuàng)建一個(gè)WinForm程序,窗體Form1的設(shè)計(jì)界面如圖10-12所示。圖10-12設(shè)計(jì)界面(2)添加成員變量,并在Form_Load事件中添加如下代碼。SqlConnectioncn=newSqlConnection("DataSource=(local);UserID=sa;Password=41919;InitialCatalog=northwind"); //創(chuàng)建連接SqlCommandcmd=newSqlCommand(); //創(chuàng)建命令privatevoidForm1_Load(objectsender,EventArgse){try{cn.Open();cmd.CommandText="selectcustomeridfromcustomers";cmd.Connection=cn;

SqlDataReaderdr=cmd.ExecuteReader(); //執(zhí)行記錄查詢(xún)while(dr.Read()) //循環(huán)讀取記錄{comboBox1.Items.Add(dr[0]); //裝載記錄值}}catch(SqlExceptionex){MessageBox.Show(ex.Message);}finally{cn.Close();}}(3)保存并運(yùn)行程序,結(jié)果如圖10-13所示。圖10-13運(yùn)行結(jié)果10.3.4使用DataAdapter對(duì)象使用Command對(duì)象執(zhí)行查詢(xún)操作后,在使用DataReader對(duì)象的Read方法就可以從數(shù)據(jù)庫(kù)中檢索出數(shù)據(jù),但DataReader對(duì)象不能處理表和記錄間的復(fù)雜關(guān)系。為此,ADO.NET引入了另一個(gè)核心的對(duì)象DataSet(數(shù)據(jù)集)。那么DataSet是如何從數(shù)據(jù)庫(kù)中獲得數(shù)據(jù)的呢?我們采用的是DataAdapter(數(shù)據(jù)適配器)對(duì)象來(lái)完成這個(gè)任務(wù)。數(shù)據(jù)適配器(DataAdapter)對(duì)象用來(lái)實(shí)現(xiàn)數(shù)據(jù)源和DataSet數(shù)據(jù)集之間的數(shù)據(jù)交換。在很多應(yīng)用程序中,這意味著借助于DataAdapter從數(shù)據(jù)庫(kù)將數(shù)據(jù)讀入DataSet,然后將更改后的數(shù)據(jù)從DataSet傳回?cái)?shù)據(jù)庫(kù)。DataAdapter可以在任何數(shù)據(jù)源和數(shù)據(jù)集之間移動(dòng)數(shù)據(jù)。對(duì)每一種類(lèi)型的NETFramework數(shù)據(jù)提供者來(lái)說(shuō),都有一個(gè)DataAdapter類(lèi)。所以才會(huì)有OleDbDataAdapter和SqlDataAdapter類(lèi),并且它們都提供相同的屬性和方法。將來(lái)要發(fā)布的所有?.NETDataProvider都將包含它們自己的DataAdapter,因?yàn)镈ataAdapter必須知道如何從特定的數(shù)據(jù)源讀取數(shù)據(jù)以及更新該數(shù)據(jù)源。除了名稱(chēng)和少數(shù)其他細(xì)節(jié)(比如如何處理參數(shù))之外,使用OleDbDataAdapter和SqlDataAdapter的方法是完全一樣的。表10-11說(shuō)明了SqlDataReader對(duì)象的屬性和方法,OleDbDataAdapter對(duì)象的屬性和方法與之類(lèi)似。表10-11SqlDataAdapter的屬性和方法1.創(chuàng)建DataAdapter在聲明DataAdapter對(duì)象時(shí),你可以向它傳遞作為參數(shù)的查詢(xún)字符串和Connection對(duì)象來(lái)初始化該DataAdapter。DataAdapter會(huì)檢查Connection對(duì)應(yīng)的連接是否已打開(kāi),如果沒(méi)有打開(kāi),就自動(dòng)打開(kāi)該連接并在方法調(diào)用結(jié)束時(shí)關(guān)閉該連接。這種做法適合于下面的情況:應(yīng)用程序已經(jīng)設(shè)置好Connection對(duì)象的屬性并且打開(kāi)連接只是為了填充數(shù)據(jù)集。下面的例子說(shuō)明了如何創(chuàng)建一個(gè)SqlDataAdapter類(lèi)的對(duì)象,并用該對(duì)象將Pubs數(shù)據(jù)庫(kù)的Titles表中所有的數(shù)據(jù)存入DataSet數(shù)據(jù)集中。//創(chuàng)建和打開(kāi)連接stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs";SqlConnectioncn=newSqlConnection(constr);//創(chuàng)建數(shù)據(jù)適配器對(duì)象SqlDataAdapterda=newSqlDataAdapter("select*fromTitles",cn);//裝入數(shù)據(jù)集的代碼DataSetds=newDataSet();da.Fill(ds,"Title");//綁定數(shù)據(jù)集到窗體控件的代碼可以放在這里…下例說(shuō)明了如何通過(guò)OleDbAdapter訪問(wèn)Access數(shù)據(jù)庫(kù)db1的Student表:stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+"DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);OleDbDataAdapterda=newOleDbDataAdapter("select*fromstudent",cn);//創(chuàng)建適配器對(duì)象DataSetds=newDataSet();da.Fill(ds,"Student"); //填充數(shù)據(jù)集2.DataAdapter對(duì)象的關(guān)鍵方法DataAdapter提供在數(shù)據(jù)集和數(shù)據(jù)源之間移動(dòng)數(shù)據(jù)的特定方法。可以使用DataAdapter執(zhí)行下列操作:(1)檢索數(shù)據(jù)庫(kù)中的行并將它們裝入到數(shù)據(jù)集的相應(yīng)數(shù)據(jù)表中。如要檢索數(shù)據(jù)存儲(chǔ)中的行并把它們裝入數(shù)據(jù)集,請(qǐng)使用SqlDataAdapter或OleDbDataAdapter的Fill方法。調(diào)用該方法時(shí),它會(huì)調(diào)用數(shù)據(jù)存儲(chǔ)中的SQLSELECT語(yǔ)句。執(zhí)行該方法將打開(kāi)和關(guān)閉連接對(duì)象。(2)將對(duì)數(shù)據(jù)集表的更改寫(xiě)回相應(yīng)的數(shù)據(jù)存儲(chǔ)。如要將對(duì)數(shù)據(jù)集表的更改寫(xiě)到數(shù)據(jù)存儲(chǔ),請(qǐng)使用該適配器的Update方法。調(diào)用該方法時(shí),根據(jù)受影響的記錄狀態(tài)是新建、更改或刪除,它將執(zhí)行相應(yīng)的SQL的INSERT、UPDATE或DELETE語(yǔ)句。執(zhí)行該方法將打開(kāi)和關(guān)閉連接對(duì)象。下面的代碼段演示了如何使用這兩種方法。//創(chuàng)建和打開(kāi)連接stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs";SqlConnectioncn=newSqlConnection(constr);//創(chuàng)建數(shù)據(jù)適配器對(duì)象SqlDataAdapterda=newSqlDataAdapter("select*fromTitles",cn);//裝入數(shù)據(jù)集的代碼DataSetds=newDataSet();da.Fill(ds,"Titles");//下面可添加代碼以在本地使用DataSet操作數(shù)據(jù)…//將DataSet的更新傳回?cái)?shù)據(jù)源da.Update(ds.Tables["Titles"]);3.熟悉更新的概念通過(guò)使用DataAdapter的Update方法可以使用DataSet來(lái)更新數(shù)據(jù)庫(kù)中的數(shù)據(jù),該方法的參數(shù)有三種:(1)?DataTable對(duì)象:該對(duì)象用作更新操作的數(shù)據(jù)源。(2)??DataSet加上DataTable的名稱(chēng):是指明將特定表用作更新操作所用數(shù)據(jù)源的另一種方法(如果不指定表名,該命令會(huì)使用名為T(mén)able的DataTable)。(3)??DataRow對(duì)象數(shù)組:只有這個(gè)數(shù)組中的記錄被用作更新操作的數(shù)據(jù)源。表中的行是按一定順序發(fā)送到數(shù)據(jù)庫(kù)的,當(dāng)需要對(duì)記錄更新的順序進(jìn)行進(jìn)一步控制時(shí),可以使用該數(shù)組。在所有情況下,Update方法都會(huì)返回已經(jīng)成功更新的行的數(shù)目。用ADO.NET執(zhí)行更新的關(guān)鍵在于DataAdapter對(duì)象的三個(gè)屬性:InsertCommand,UpdateCommand和DeleteCommand。這三個(gè)屬性連同SelectCommand就好象DataAdapter的四個(gè)幫手一樣,各自執(zhí)行特定的任務(wù)。以下是更新機(jī)制的工作方式。發(fā)出Update命令時(shí),DataAdapter檢查被指定為要進(jìn)行更新操作的每一行的RowState屬性。當(dāng)該狀態(tài)是Added時(shí),DataAdapter就發(fā)出在InsertCommand屬性中指定的SQL命令。如

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論