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

下載本文檔

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

文檔簡介

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

1.關(guān)系模型

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

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

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

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

3)主鍵主鍵唯一標(biāo)識了表的每一行。主鍵可以是一個字段,也可以是幾個字段的組合。對表中的每一行(記錄)來說,主鍵的值都是惟一的。例如,“學(xué)號”字段是“學(xué)生信息表”的主鍵,因為任何兩個學(xué)生的學(xué)號都不相同。在Access中,可以通過鼠標(biāo)操作的方式為表添加一個主鍵,如圖10-4中學(xué)號上有個標(biāo)識。圖10-4具有主鍵的學(xué)生信息表

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

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

3.SQL語言

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Server.NETDataProvider,OLEDB.NETDataProviderforSQL和OLEDBProviderforMicrosoftJet等。你也可以為任意數(shù)據(jù)源編寫自定義的.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ù)提供組件用于訪問如Access、Oracle等數(shù)據(jù)源。當(dāng)然OLEDB組件也可以用于訪問SQLServer數(shù)據(jù)源,但由于有中間層的加入,性能不是很好。該組件屬于System.Data.OleDb命名空間。上面兩種數(shù)據(jù)提供組件,都實現(xiàn)了Connection對象、Command對象、DataReader對象和DataAdapter對象的模型,如表10-3所示。此外,我們還將使用到System.Data命名空間,它也是.NETFramework用來存取數(shù)據(jù)的主要組件。表10-4介紹了System.Data的幾個常見的子類。各個子類的關(guān)系如圖10-7所示。表10-3兩種數(shù)據(jù)提供組件中的對象表10-4System.Data的幾個常見的子類圖10-7System.Data中各個子類的關(guān)系使用VisualStudio2005創(chuàng)建程序時,系統(tǒng)將默認(rèn)應(yīng)用System.Data.dll組件。因此,不需要再添加對System.Data的引用,直接在程序中使用using把命名空間導(dǎo)入即可。如果要引用該組件,請在項目的引用上單擊,添加相應(yīng)的組件,如圖10-8所示。

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

【例10-1】使用控制臺程序建立對SQLServer的連接。usingSystem;usingSystem.Data.SqlClient;usingSystem.Data;classTestConnection{staticvoidMain(){SqlConnectioncn=newSqlConnection();//創(chuàng)建一個連接對象try{stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=NorthWind";cn.ConnectionString=constr; //設(shè)置連接字符串cn.Open();Console.WriteLine("連接已打開");}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對象在打開了連接之后,你可以決定是在連接環(huán)境還是非連接環(huán)境下工作。對前一種情況,通??梢詣?chuàng)建一個Command對象,該對象包含一個選擇查詢(從數(shù)據(jù)庫讀取數(shù)據(jù))或者一個操作查詢(更新數(shù)據(jù)),然后執(zhí)行Executexxx方法(確切的名稱取決于查詢的類型)。Command對象按數(shù)據(jù)庫類型也分為兩大類:SqlCommand用于執(zhí)行SQLServer中的命令,OleDbCommand對象用于執(zhí)行非SQLServer數(shù)據(jù)庫中的命令。表10-7和表10-8分別說明了兩種Command對象的屬性和方法。表10-7SqlCommand的屬性和方法表10-8OleDbCommand的屬性的方法1.創(chuàng)建Command對象對象的關(guān)鍵屬性是CommandText(執(zhí)行操作查詢或選擇查詢的SQL文本)和Connection(查詢所基于的連接)。你可以逐個設(shè)置這些屬性,如下列代碼所示://創(chuàng)建和打開連接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í)行語句,返回被影響的行數(shù)intrecords=cmd.ExecuteNonQuery();Debug.Write(records); //輸出1//關(guān)閉連接cn.Close();也可以將這兩個值傳遞給Command對象的構(gòu)造方法,這樣代碼更簡潔:OleDbCommandcmd=newOleDbCommand(sqlstr,cn);2.發(fā)出數(shù)據(jù)庫命令正如在前面的代碼中所看到的,使用ExecuteNonQuery方法(它返回受到該語句影響的記錄的數(shù)目),可以通過Command對象來執(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)然,從安全及排錯的角度來說,應(yīng)該將它(以及所有的數(shù)據(jù)庫操作)放在try代碼塊中保護(hù)起來:try{ //運(yùn)行查詢;獲取受影響記錄的數(shù)目 intrecords=cmd.ExecuteNonQuery();}catch{ //在這里處理錯誤 ...}finally{ //總是關(guān)閉連接 cn.Close();}【例10-2】使用Windows程序操作SQLServer數(shù)據(jù)庫,步驟如下:(1)首先創(chuàng)建一個WinForm程序,對窗體Form1的設(shè)計界面如圖10-10所示。圖10-10設(shè)計界面(2)導(dǎo)入所需的命名空間,然后在代碼區(qū)定義成員變量及方法。SqlConnectioncn=newSqlConnection("DataSource=(local);UserID=sa;Password=41919;InitialCatalog=northwind");SqlCommandcmd=newSqlCommand();privateboolcheckSame(stringbh) //判斷輸入的客戶號是否重復(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("存在相同的客戶號,請重新輸入!");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對象此對象用于從數(shù)據(jù)源中獲取只讀和只進(jìn)數(shù)據(jù)。DataReader在任何時候都只在內(nèi)存中保存一行數(shù)據(jù),減少了內(nèi)存開銷,提高了性能。和Connection對象一樣,DataReader對象也包含兩種類型:SqlDataReader和OleDbDataReader。表10-9和表10-10分別說明了兩種DataReader對象的屬性和方法。使用DataReader對象也很簡單:調(diào)用它的Read方法前進(jìn)到數(shù)據(jù)集的下一行,并檢查其返回值。如果返回值為false,則已經(jīng)到了數(shù)據(jù)集的末端;如果返回值為true,則還有更多的記錄。根據(jù)這個布爾函數(shù),可以使用DataReader對象建立循環(huán)://創(chuàng)建和打開連接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)不必再對行進(jìn)行處理的時候,一定要關(guān)閉DataReader對象。這樣可以釋放客戶端計算機(jī)和服務(wù)器上的資源,并使得該連接可以再度為其他命令所用。實際上,當(dāng)連接上有激活的DataReader對象時,你就不能在該連接上發(fā)出任何其他命令。DataReader在使用一個連接時,在該連接上惟一可以執(zhí)行的命令就是Close方法。可以通過連接的State屬性檢查它是否可用。DataReader對象沒有這種屬性,不過可以通過它的IsClosed屬性來檢查它是否已經(jīng)關(guān)閉。【例10-3】使用Windows程序顯示數(shù)據(jù),步驟如下:(1)首先創(chuàng)建一個WinForm程序,窗體Form1的設(shè)計界面如圖10-12所示。圖10-12設(shè)計界面(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í)行記錄查詢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對象使用Command對象執(zhí)行查詢操作后,在使用DataReader對象的Read方法就可以從數(shù)據(jù)庫中檢索出數(shù)據(jù),但DataReader對象不能處理表和記錄間的復(fù)雜關(guān)系。為此,ADO.NET引入了另一個核心的對象DataSet(數(shù)據(jù)集)。那么DataSet是如何從數(shù)據(jù)庫中獲得數(shù)據(jù)的呢?我們采用的是DataAdapter(數(shù)據(jù)適配器)對象來完成這個任務(wù)。數(shù)據(jù)適配器(DataAdapter)對象用來實現(xiàn)數(shù)據(jù)源和DataSet數(shù)據(jù)集之間的數(shù)據(jù)交換。在很多應(yīng)用程序中,這意味著借助于DataAdapter從數(shù)據(jù)庫將數(shù)據(jù)讀入DataSet,然后將更改后的數(shù)據(jù)從DataSet傳回數(shù)據(jù)庫。DataAdapter可以在任何數(shù)據(jù)源和數(shù)據(jù)集之間移動數(shù)據(jù)。對每一種類型的NETFramework數(shù)據(jù)提供者來說,都有一個DataAdapter類。所以才會有OleDbDataAdapter和SqlDataAdapter類,并且它們都提供相同的屬性和方法。將來要發(fā)布的所有?.NETDataProvider都將包含它們自己的DataAdapter,因為DataAdapter必須知道如何從特定的數(shù)據(jù)源讀取數(shù)據(jù)以及更新該數(shù)據(jù)源。除了名稱和少數(shù)其他細(xì)節(jié)(比如如何處理參數(shù))之外,使用OleDbDataAdapter和SqlDataAdapter的方法是完全一樣的。表10-11說明了SqlDataReader對象的屬性和方法,OleDbDataAdapter對象的屬性和方法與之類似。表10-11SqlDataAdapter的屬性和方法1.創(chuàng)建DataAdapter在聲明DataAdapter對象時,你可以向它傳遞作為參數(shù)的查詢字符串和Connection對象來初始化該DataAdapter。DataAdapter會檢查Connection對應(yīng)的連接是否已打開,如果沒有打開,就自動打開該連接并在方法調(diào)用結(jié)束時關(guān)閉該連接。這種做法適合于下面的情況:應(yīng)用程序已經(jīng)設(shè)置好Connection對象的屬性并且打開連接只是為了填充數(shù)據(jù)集。下面的例子說明了如何創(chuàng)建一個SqlDataAdapter類的對象,并用該對象將Pubs數(shù)據(jù)庫的Titles表中所有的數(shù)據(jù)存入DataSet數(shù)據(jù)集中。//創(chuàng)建和打開連接stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs";SqlConnectioncn=newSqlConnection(constr);//創(chuàng)建數(shù)據(jù)適配器對象SqlDataAdapterda=newSqlDataAdapter("select*fromTitles",cn);//裝入數(shù)據(jù)集的代碼DataSetds=newDataSet();da.Fill(ds,"Title");//綁定數(shù)據(jù)集到窗體控件的代碼可以放在這里…下例說明了如何通過OleDbAdapter訪問Access數(shù)據(jù)庫db1的Student表:stringconstr="Provider=Microsoft.Jet.OLEDB.4.0;"+"DataSource="+Application.StartupPath+"\\db1.mdb";OleDbConnectioncn=newOleDbConnection(constr);OleDbDataAdapterda=newOleDbDataAdapter("select*fromstudent",cn);//創(chuàng)建適配器對象DataSetds=newDataSet();da.Fill(ds,"Student"); //填充數(shù)據(jù)集2.DataAdapter對象的關(guān)鍵方法DataAdapter提供在數(shù)據(jù)集和數(shù)據(jù)源之間移動數(shù)據(jù)的特定方法??梢允褂肈ataAdapter執(zhí)行下列操作:(1)檢索數(shù)據(jù)庫中的行并將它們裝入到數(shù)據(jù)集的相應(yīng)數(shù)據(jù)表中。如要檢索數(shù)據(jù)存儲中的行并把它們裝入數(shù)據(jù)集,請使用SqlDataAdapter或OleDbDataAdapter的Fill方法。調(diào)用該方法時,它會調(diào)用數(shù)據(jù)存儲中的SQLSELECT語句。執(zhí)行該方法將打開和關(guān)閉連接對象。(2)將對數(shù)據(jù)集表的更改寫回相應(yīng)的數(shù)據(jù)存儲。如要將對數(shù)據(jù)集表的更改寫到數(shù)據(jù)存儲,請使用該適配器的Update方法。調(diào)用該方法時,根據(jù)受影響的記錄狀態(tài)是新建、更改或刪除,它將執(zhí)行相應(yīng)的SQL的INSERT、UPDATE或DELETE語句。執(zhí)行該方法將打開和關(guān)閉連接對象。下面的代碼段演示了如何使用這兩種方法。//創(chuàng)建和打開連接stringconstr="DataSource=(local);UserID=sa;Password=41919;InitialCatalog=pubs";SqlConnectioncn=newSqlConnection(constr);//創(chuàng)建數(shù)據(jù)適配器對象SqlDataAdapterda=newSqlDataAdapter("select*fromTitles",cn);//裝入數(shù)據(jù)集的代碼DataSetds=newDataSet();da.Fill(ds,"Titles");//下面可添加代碼以在本地使用DataSet操作數(shù)據(jù)…//將DataSet的更新傳回數(shù)據(jù)源da.Update(ds.Tables["Titles"]);3.熟悉更新的概念通過使用DataAdapter的Update方法可以使用DataSet來更新數(shù)據(jù)庫中的數(shù)據(jù),該方法的參數(shù)有三種:(1)?DataTable對象:該對象用作更新操作的數(shù)據(jù)源。(2)??DataSet加上DataTable的名稱:是指明將特定表用作更新操作所用數(shù)據(jù)源的另一種方法(如果不指定表名,該命令會使用名為Table的DataTable)。(3)??DataRow對象數(shù)組:只有這個數(shù)組中的記錄被用作更新操作的數(shù)據(jù)源。表中的行是按一定順序發(fā)送到數(shù)據(jù)庫的,當(dāng)需要對記錄更新的順序進(jìn)行進(jìn)一步控制時,可以使用該數(shù)組。在所有情況下,Update方法都會返回已經(jīng)成功更新的行的數(shù)目。用ADO.NET執(zhí)行更新的關(guān)鍵在于DataAdapter對象的三個屬性:InsertCommand,UpdateCommand和DeleteCommand。這三個屬性連同SelectCommand就好象DataAdapter的四個幫手一樣,各自執(zhí)行特定的任務(wù)。以下是更新機(jī)制的工作方式。發(fā)出Update命令時,DataAdapter檢查被指定為要進(jìn)行更新操作的每一行的RowState屬性。當(dāng)該狀態(tài)是Added時,DataAdapter就發(fā)出在InsertCommand屬性中指定的SQL命令。如

溫馨提示

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

最新文檔

評論

0/150

提交評論