470 likes | 614 Views
第十七章 資料庫. 1 7 - 1 資料庫基本認識 1 7 - 2 什麼是 ADO.NET 1 7 - 3 使用對話框連結資料庫 1 7 - 4 使用程式連結資料庫 1 7 - 5 資料繫結 ﹝ DataBinding ﹞ 類別 1 7 - 6 資料的編輯 1 7 - 7 資料表單精靈 習題. 1 7 - 1 資料庫基本認識. 將資料存入硬碟的方式有二種 , 其一是檔案 , 其二是資料庫。此二種模式最大的差別 , 在於資料庫與一般使用者之間多了一個資料庫管理系統 (Database Management System, DBMS) 。
E N D
第十七章 資料庫 • 1 7 - 1 資料庫基本認識 • 1 7 - 2 什麼是ADO.NET • 1 7 - 3 使用對話框連結資料庫 • 1 7 - 4 使用程式連結資料庫 • 1 7 - 5 資料繫結﹝DataBinding ﹞類別 • 1 7 - 6 資料的編輯 • 1 7 - 7 資料表單精靈 • 習題
1 7 - 1 資料庫基本認識 • 將資料存入硬碟的方式有二種, 其一是檔案, 其二是資料庫。此二種模式最大的差別, 在於資料庫與一般使用者之間多了一個資料庫管理系統(Database Management System, DBMS)。 • 於檔案模式中, 程式設計者必須了解資料的型態、長度, 並親自撰寫程式才能取得硬碟資料; 於資料庫模式中, 程式設計者的工作就輕鬆了, 因為程式設計者與硬碟之間多了一個資料庫管理系統, 就如同您身旁有一位秘書或出門有司機一樣, 凡事只要動口而不必動手, 當然工作會輕鬆愉快。所以, 使用者可使用不同的應用程式, 或甚至不寫任何程式, 即可透過資料庫管理系統取得資料。
資料表(Table) • 假設有員工基本資料如下, 若將以下資料以資料庫模式存入硬碟, 則稱此檔案為資料表。
欄位(Field) • 上圖中的直向資料, 例如編號、姓名、年齡及職務等稱為欄位, 本例共有五個欄位。
記錄(Record) • 上圖中的橫向資料, 例如A01 、張建原、男、教師稱為一筆記錄, 本例共有四筆記錄。
資料項(Data Item) • 上圖中的"A01" 、" 張建原" 或" 主任" 等單一資料稱為資料項, 本例共有二十個資料項, 資料項是資料庫的最小單位。
資料庫(Database) • 眾多相關資料表的集合稱為資料庫。
資料集(DataSet or RecordSet) • 我們可從一個或一個以上的資料表中, 使用SQL 敘述萃取某些欄位,而形成一個資料集合, 此一集合即稱為資料集。
索引(Index) • 讀者可以想像一下, 一本國語字典至少都有兩種索引, 一是注音索引表, 另一是部首索引表。各位可以注意每個索引表都只有兩個欄位, 一是國字本身, 一是頁數, 而較大的字典甚至還有電信明碼或四角號碼等索引。電腦的索引原理也是相同的, 增加索引的目的是用來增加查詢的速度。對資料庫而言, 我們只要指定哪些欄位要建立成索引之後, 資料庫就會自動幫我們建立索引區, 然後根據索引搜尋資料, 並且針對這些欄位加以排序。但要注意一點的是, 索引在資料庫中是獨立的資料區域, 因此會佔據額外的硬碟空間, 所以, 只在可加速搜尋的欄位加裝索引即可, 以免浪費硬碟空間。
1 7 - 2 什麼是ADO.NET • ADO.NET (ActiveX Data Objects for the .NET Framework)是微軟所提出新一代的資料存取服務, 並將這些服務提供給.NET 程式設計人員使用。透過ADO.NET 所提供的元件, 您就可以存取關聯式資料庫、XML 和應用程式資料。ADO.NET 支援數種開發需求, 包括建立前端(Front End) 資料庫用戶端,以及應用程式、工具、語言或Internet 瀏覽器使用的中介層商務物件(MiddleTier Business Object)。
ADO.NET 包含了以下六個命名空間(Namespace): • System.Data ADO.NET 架構的核心命名空間, 主要是包含了資料庫基本物件。例如,資料表(DataTable)、欄位(DataColumn)、列(DataRow)及資料集(DataSet)等。 • System.Data.Common 包含.NET 資料提供者(Data Provider)共用的類別。 • System.Data.OleDb 其中的類別可讓您連接至OLE DB 的資料來源、對來源執行SQL 命令及讀取結果。 • System.Data.SqlClient 組成SQL Server 的.NET 資料提供者的類別, 允許您連接到SQL Server、執行SQL 命令並讀取結果。System.Data.SqlClient 命名空間與System.Data.OleDb 命名空間類似, 但它是針對存取SQL Server 及更新版本而進行最佳化。
System.Data.SqlTypes 提供SQL Server 內原生資料(Native Data)型別的類別。這些類別會提供較安全、較快速的資料型別, 來替代其他的資料型別。使用這個命名空間中的類別, 可避免萬一發生遺失精確度的情況時所造成的型別轉換錯誤。 • System.Xml 針對處理XML 文件, 所提供標準架構的類別。 用戶端應用程式透過ADO.NET 元件, 存取後端資料庫的架構如下圖所示:
.NET 資料提供者(Data Provider) • .NET 資料提供者的用途是連接資料庫、執行命令和擷取結果。這些結果可能會經過直接處理、放入ADO.NET DataSet 物件、與來自多種來源的資料合併, 或者在各層間遠端傳遞。 • 下列表格列出構成.NET 資料提供者的五個核心物件。
. NET Framework 包含二種資料提供者: • 1. SQL Server .NET 資料提供者:使用自己的通訊協定與SQL Server 通訊,用來直接存取SQL Server, 會得到最佳效能, 其命名空間為System.Data.SqlClient 。 • 2. OLE DB .NET 資料提供者:使用原生OLE DB 來啟用資料存取, 可存取各種OLE DB 資料來源。例如, Access、OLAP Services 、Directory Services或其他異質資料庫等, 其命名空間為System.Data.OleDb 。 • 以上兩種資料提供者的差異, 比較如下圖。
1 7 - 3 使用對話框連結資料庫 • 在上一節中我們認識了.NET 資料提供者的核心物件, 現在就讓我們來學習如何在VB.NET 的設計階段, 能夠自動產生這些物件, 並且透過這些物件, 只要寫極少的程式, 就可以連結到資料庫。
範例17-3a • Access 資料庫"C:\CSBook\Northwind.mdb"『客戶』資料表的內容如下, 請利用ADO.NET 提供的物件, 顯示出來。
1 7 - 4 使用程式連結資料庫 • 在17-3 節中, 我們雖然學到了透過滑鼠的拖拉, 就可以自動產生ADO.NET 的物件, 但這種做法, 卻不是最好的方式, 道理很簡單, 因為沒有彈性可言。例如, 我們無法從兩個以上的資料表中擷取資料。再者, 我們無法決定何時才要真正的連上資料庫。最後, 也是最重要的一點, 我們無法傳送SQL 敘述至後端的資料庫。 • 在Database 程式設計中, 如何由前端傳送SQL 敘述至後端的資料庫, 是一項非常重要的主題。要改進上述的這些缺點, 只有靠程式敘述, 先產生ADO.NET 提供的物件之後, 再進一步地控制這些物件的屬性及方法, 來完成我們的工作。以下是C#.NET 程式存取資料庫的步驟, 分別是選擇資料提供者、建立Connection 物件、建立Command 物件、建立DataAdapter 物件、建立DataSet 物件及建立與連結DataGrid 物件, 分別說明如下:
選擇資料提供者(Data Provider) • 我們必須要先確定欲連結資料庫的種類, 以選擇適當的.NET 資料提供者。例如, SQL Server 7.0 以上的版本, 要在程式最開始的地方, 加上以下敘述: using System.Data.SqlClient; • 若要連結OLE DB 資料來源, 像是Access 資料庫, 則要加上以下敘述: using System.Data.OleDb;
建立Connection 物件 • 連結資料庫的下一步是建立Connection 物件, 並設定ConnectionString 屬性。首先, 建立物件的語法如下: OleDbConnection 物件名稱= new OleDbConnection(); • 其次, 設定ConnectionString 屬性的語法如下: 物件名稱.ConnectionString = "連結字串"; • 以上物件的建立與屬性的設定, 亦可合併如下: OleDbConnection 物件名稱= new OleDbConnection(" 連結字串"); • 例如, 假設欲連結Access 檔案, 此檔案的路徑及檔名為"C:\CsBook\Northwind.mdb", 則所需敘述如下: OleDbConnection cn = new OleDbConnection ( ); cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=C:\\CsBook\\Northwind.
在" 連結字串" 中, 我們看到了「Provider」以及「Data Source」兩個屬性, 「Provider」是用來設定與資料庫連線時所使用的驅動程式, 而「DataSource」則是用來告訴系統我們要連結的Access 檔案在什麼地方。 • 最後, 別忘了呼叫Open 方法, 建立和資料庫的連結。其敘述如下: c n . Op e n ( ) ; • 另外, 若是我們要連結至SQL Server 的話, 其敘述如下: // 別忘了要在程式最開始的地方, 加上這一行: using System.Data.SqlClient SqlConnection cn = new SqlConnection(); cn.ConnectionString = "Server=ComputerName;" + "Database=DatabaseName;" + "UID=UserID; PWD=Password"; • 在" 連結字串" 中, 我們看到了「Server」、「Database」、「UID」以及「PWD」四個屬性, 「Server」是用來指定SQL Server 資料庫是在那一台電腦上, 「Database」是用來指定資料庫的名稱, 「UID」是用來指定登入資料庫的帳號, 而「PWD」則是用來指定登入資料庫的密碼。
建立Command 物件 • 與資料庫建立連結後, 我們必須藉由建立『Command』物件, 傳送SQL敘述給後端資料庫, 並與Connection 物件連結, 其語法如下: OleDbCommand 物件名稱= new OleDbCommand( ); 物件名稱.CommandText = "SQL 敘述"; 物件名稱.Connection = cn; //cn 是Connection 物件,Connection 屬性用來連結至Connection 物件 • 以上三個敘述亦可合併如下: OleDbCommand 物件名稱= new OleDbCommand("SQL 敘述", cn); //cn 是Connection 物件 • 例如, 我們要藉由以上敘述的cn 物件, 找出『客戶』資料表中的所有紀錄, 其敘述如下: OleDbCommand cm = new OleDbCommand(); cm.CommandText = "Select * From 客戶"; cm.Connection = cn;
建立DataAdapter 物件 • 當我們設定SQL 敘述後, 必須藉由建立DataAdapter 物件與Command 物件連結, 並執行SQL 敘述擷取資料至用戶端, 其語法如下: OleDbDataAdapter 物件名稱; 物件名稱= new OleDbDataAdapter(cm); //cm 是Command 物件 • 以上二個敘述亦可合併如下: OleDbDataAdapter da = new OleDbDataAdapter(cm);
建立DataSet 物件 • 當DataAdapter 物件擷取資料至用戶端後, 利用Fill 方法, 將資料填入DataSet 物件。例如, 我們要從上例的cm 物件, 將『客戶』資料表中的所有紀錄填入DataSet 物件, 其敘述如下: OleDbDataAdapter da = new OleDbDataAdapter(cm); DataSet ds = new DataSet(); d a . F i l l ( d s , " 客戶" ) ;
建立與連結DataGrid 物件 • 欲將取得的資料, 藉由表單輸出, 必須先於表單配置DataGrid 物件。其次, 再設定DataSource 屬性, 如以下敘述: dataGrid1.DataSource = ds.Tables[" 客戶"]; // 將結果顯示至DataGrid 物件
範例17-4a • 使用本節所介紹的程式敘述, 產生ADO.NET 物件, 重做範例17-3a, 並將結果顯示出來。
範例17-4b • 示範不使用『Command』物件, 重做範例17-4a, 並請自行比較兩範例的程式碼。
1 7 - 5 資料繫結﹝DataBinding ﹞類別 • 資料繫結可以讓控制項與資料來源產生繫結, 顯示資料來源的資料。我們在此介紹兩種資料繫結, 分別是單一欄位與多個欄位值的繫結。
單一欄位值的資料繫結 • 有一些控制項(Control), 像是TextBox、CheckBox 、RadioButton 等, 可以與資料來源結合, 用來顯示某一欄位的值, 其語法如下: Control.DataBindings.Add("Property",DataSource, "DataMember"); • Property:是控制項的某個屬性。 • DataSource:可以是DataSet、DataTable 或DataView。 • DataMember:如果「DataSource」是DataSet, DataMember 就是「資料表.欄位名稱」; 如果「DataSource」是DataTable, DataMember 就是「欄位名稱」。例如, 以下敘述將『客戶』資料表的『客戶編號』欄位的值, 由名稱為"txt 客戶編號" 的TextBox 控制項顯示出來。 txt 客戶編號.DataBindings.Add("Text",ds," 客戶.客戶編號");
多個欄位值的資料繫結 • 最常見的控制項為DataGrid, 可以顯示多個欄位的多筆記錄。例如, 以下敘述將『客戶』資料表的內容, 由DataGrid 元件顯示出來。 DataGrid1.DataSource = ds; //ds 為DataSet DataGrid1.DataMember = "客戶";
範例17-5a • 將Access 資料庫"C:\CsBook\Northwind.mdb"『客戶』資料表的內容, 利用本節介紹的兩種資料繫結, 顯示出來。
記錄指標的移動 • 當DataSource 與控制項產生資料繫結之後, 我們可以利用BindingManagerBase 類別來處理記錄指標。而這個類別主要利用兩個重要的屬性, 來處理記錄指標。請看下表:
我們若要建立BindingManagerBase 物件, 必須使用BindingContext 類別建立或傳回被收納資料繫結控制項所使用之資料來源的BindingManagerBase 。最常見的情形是使用Form 類別的BindingContext 來傳回表單上資料繫結控制項的BindingManagerBase 物件。例如, 以下敘述可得到BindingManagerBase 物件bm, 以管理表單的資料繫結與處理記錄指標: BindingManagerBase bm; bm = this.BindingContext[ds," 客戶"]; //this 為表單本身 • 由以上敘述取得bm 之後, 就可以透過此物件移動記錄指標了。例如: bm.Position += 1; // 將記錄向後移動一筆 bm.Position -= 1; // 將記錄向前移動一筆
範例17-6a • 使用資料繫結, 重做範例17-5a, 使得使用者可使用上一筆、下一筆、首筆及尾筆等按鈕, 而移動記錄。
記錄的查詢 • 在設計資料庫系統時, 前端維護畫面一定要具備四項功能:新增、修改、刪除及查詢。其中查詢功能是利用SQL 的Select 敘述, Where 條件則是運用一些技巧得到。例如, 維護畫面設計如下圖所示, 查詢條件是如果使用者在" 客戶編號"文字欄(txt 客戶編號) 內有輸入值, 我們就找出"客戶編號"為該值的資料; 如果使用者沒有輸入任何值, 我們就找出所有的資料。
運用技巧設計Select + Where 條件之SQL 敘述, 其敘述如下: string strQuery = "Select * From 客戶"; if (txt 客戶編號.Text != "") strQuery = strQuery + " Where 客戶編號= " + "\'" + txt 客戶編號.Text + "\'"; • 然後將所得到之SQL 敘述傳給後端資料庫, 並將自資料庫擷取之記錄, 傳入DataSet 物件(ds)。其敘述如下: c n . Op e n ( ) ; cm.CommandText = strQuery; cm.Connection = cn; da = new OleDbDataAdapter(cm); d a . F i l l ( d s , " 客戶" ) ; • 最後利用資料繫結, 將所擷取之記錄顯示出來。其敘述如下: ' 顯示單一欄位值的資料繫結 t x t 客戶編號. Data B i n d in g s . A d d ( " Te x t " , d s , " 客戶.客戶編號" ) ; t x t 公司名稱. Data B i n d in g s . A d d ( " Te x t " , d s , " 客戶.公司名稱" ) ; t x t 連絡人. Da t a B i n d in g s . A d d ( " Te x t " , d s , " 客戶.連絡人" ) ; ' 顯示多個欄位值的資料繫結 dataGrid1.DataSource = ds; dataGrid1.DataMember = "客戶";
範例17-6b • 重做範例17-6a, 並加入查詢之功能。
記錄的新增 • 如果要新增一筆記錄至『客戶』資料表, 我們可利用BindingContext 物件的AddNew 方法, 其敘述如下: this.BindingContext[ds," 客戶"].AddNew();//this 為表單本身 / / 利用以下敘述將值填入各個欄位 d s .T a b l e s [ " 客戶" ] .Rows [ bm . P o s i t i o n ] [ " 客戶編號" ] = txt 客戶編號.Text; d s .T a b l e s [ " 客戶" ] .Rows [ bm . P o s i t i o n ] [ " 公司名稱" ] = txt 公司名稱.Text; d s . Ta b l e s [ " 客戶" ] .R ows [ b m . P o s i t io n ] [ " 連絡人" ] = txt 連絡人.Text;
但是要注意, 這時並未將資料寫入資料庫, 必須再使用以下敘述, 將資料真正的寫入資料庫。 OleDbCommandBuilder cb = new OleDbCommandBuilder(da); //da 為DataAdapter 物件 c b . Da t a Ad a p t e r . Up d a t e ( d s .T a b l e s [ " 客戶" ] ) ; //ds 為DataSet 物件 • 那如果我們做了一半卻想取消這筆新增的記錄, 又要如何處理呢?利用以下敘述即可。 this.BindingContext[ds, "客戶"].CancelCurrentEdit(); t h i s . d s . R e j e c t C h a n g e s ( ) ;
記錄的修改 • 如果要修改一筆記錄比較單純, 我們可直接將欲修改的值, 藉由TextBox填入欲修改的欄位, 其敘述如下: d s .Ta b l e s [ " 客戶" ] .R ows [ bm . P o s i t i o n ] [ " 客戶編號" ] = txt 客戶編號.Text; d s .Ta b l e s [ " 客戶" ] .R ows [ bm . P o s i t i o n ] [ " 公司名稱" ] = txt 公司名稱.Text; d s . Ta b l e s [ " 客戶" ] .R ows [ b m . P o s i t io n ] [ " 連絡人" ] = txt 連絡人.Text;
但是這時並未將資料寫入資料庫, 必須再使用以下敘述, 將資料真正的寫入資料庫。 OleDbCommandBuilder cb = new OleDbCommandBuilder(da); //da 為DataAdapter 物件 cb . DataAd a p t e r . Up d a t e ( d s .T a b l e s [ " 客戶" ] ) ; //ds 為DataSet 物件 • 或是使用以下敘述, 放棄修改。 t h i s . B i n d i n gC o n t e x t [ d s , " 客戶" ] . Ca n c e lC u r r e n t E d i t ( ) ; t h i s . d s . R e j e c t C h a n g e s ( ) ;
記錄的刪除 • 如果要刪除一筆記錄, 我們可利用BindingContext 物件的RemoeAt 方法, 其敘述如下, 敘述中Position 是記錄指標, 這樣我們才知道要刪除那一筆記錄。 th i s . Bin d i n gCo n t e x t [ d s , " 客戶" ] . R e mo v eAt ( this.BindingContext[ds," 客戶"].Position); • 同樣地, 最後要真正刪除這筆記錄, 必須再使用以下敘述, 才能將資料真正的刪除。 OleDbCommandBuilder cb = new OleDbCommandBuilder(da); //da 為DataAdapter 物件 c b . Da t a Ad a p t e r . Up d a t e ( d s .T a b l e s [ " 客戶" ] ) ; //ds 為DataSet 物件
範例17-6c • 重做範例17-6b, 並加入新增、修改、刪除之功能。
1 7 - 7 資料表單精靈 • ADO.NET 提供了" 精靈" 的功能, 讓我們可以在不用寫任何程式的情況下, 就很方便的設計出具有新增、修改以及刪除等功能的前端維護畫面,請看以下範例說明。
範例17-7a • 請使用資料表單精靈, 製作出Access 資料庫"C:\CsBook\Northwind.mdb"『客戶』資料表的前端維護畫面, 該畫面並包含移動記錄指標、新增、修改以及刪除的功能。
習題 • 1. 若某次考試成績如右: • (1) 請寫程式將以上資料以資料庫儲存。 • (2) 請寫程式讀取以上資料, 計算平均, 並顯示以上資料。 • (3) 請將平均寫入資料庫。 • 2. 假設您要開設婚姻介紹所。 • (1) 請問您的資料欄位為何? • (2) 您的新增畫面與功能為何? • (3) 您的查詢畫面與功能為何? • (4) 您的刪除畫面與功能為何?