690 likes | 827 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 資料庫基本認識. 以檔案儲存資料 檔案系統( File System )負責儲存 使用者必須自行負責資料的維護與管理 程式設計者必須了解資料的型態、長度以及檔案之間的關係,並親自撰寫程式才能取得資料
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 資料庫基本認識 • 以檔案儲存資料 • 檔案系統(File System)負責儲存 • 使用者必須自行負責資料的維護與管理 • 程式設計者必須了解資料的型態、長度以及檔案之間的關係,並親自撰寫程式才能取得資料 • 以資料庫儲存資料 • 資料庫管理系統(Database Management System, DBMS)負責資料儲存與維護,並協助管理 • 程式設計師的工作比較輕鬆,撰寫程式時只要考慮『What to do?』,不必煩心『How to do?』
Column Name(欄位名稱) Column(欄) Row (列) Item(資料項) 資料表(Table) • 資料表為相關資料項目的集合
資料集(DataSet) • 我們可從一個或一個以上的資料表中, 使用SQL 敘述萃取某些資料項,而形成一個資料集合, 此一集合即稱為資料集。 • 一個 DataSet 之中可以包含多個 Table 也可以設定 Table 之間的關聯 • ADO.NET DataSet 就像是存在記憶體之中的一個小型(離線)資料庫
鍵(Key) • 資料表之中能夠作為識別項(Identifier)的欄位稱為候選鍵(Candidate Key) • 例:學生基本資料表的『學號』與『身份證字號』欄 • 在眾多候選鍵之中挑選一個候選鍵作為主鍵(Primary Key) • 每一個資料表都應該有一個主鍵,沒有主鍵的資料表在進行資料刪除與修改時將遇到困難 • 由兩個以上的欄位組成的鍵稱為複合鍵(Composite Key) • 例:訂單明細表一般以『訂單編號』與『產品編號』組合成主鍵
索引(Index) • 為必須作為查詢依據的欄位建立索引,可以增進查詢的效率 • 例如:若必須經常執行下列查詢SELECT 編號, 姓名, 性別, 職務, 年齡FROM 員工基本資料WHERE 年齡 < 40則應該為『年齡』欄位建立索引 • 不可浮濫:太多索引反而會造成資料異動速度變慢;不要為不必要的欄位設定索引
1 7 - 2 什麼是ADO.NET? • ADO.NET (ActiveX Data Objects for the .NET Framework) 是 .NET Framework 的資料存取標準 • 使用 ADO.NET 所提供的元件可以存取關聯式資料庫、XML 和應用程式資料。
ADO.NET 的命名空間(Namespace) • System.Data ADO.NET 架構的核心命名空間, 主要是包含了資料庫基本物件。例如,資料表(DataTable)、欄位(DataColumn)、列(DataRow)及資料集(DataSet)等。 • System.Data.OleDb 其中的類別可讓您連接至 OLE DB 的資料來源、對來源執行SQL 命令存取資料。 • System.Data.SqlClient SQL Server 的 .NET 資料提供者的類別,讓您連接到 SQL Server 執行 SQL 命令存取資料。
ADO.NET 的命名空間(Namespace) • System.Data.Common 包含 .NET 資料提供者(Data Provider)共用的類別。 • System.Data.SqlTypes 提供 SQL Server 內原生資料(Native Data)型別的類別。這些類別會提供較安全、較快速的資料型別, 來替代其他的資料型別。使用這個命名空間中的類別, 可避免萬一發生遺失精確度的情況時所造成的型別轉換錯誤。 • System.Xml 針對處理 XML 文件, 所提供標準架構的類別。
用戶端應用程式透過 ADO.NET 元件存取後端資料庫的架構圖
.NET 資料提供者(Data Provider) • .NET 資料提供者的用途是 • 連接資料庫 • 執行命令 • 擷取結果 • 資料存取的結果可能會經過直接處理、放入 ADO.NET DataSet 物件、與來自多種來源的資料合併,或者在各層間遠端傳遞。
SQL .NET Data Provider VS. OLE DB .NET Data Provider • SQL Server .NET 資料提供者使用特定通訊協定與 SQL Server 通訊,用來直接存取 SQL Server,可達到最佳效能,其命名空間為 System.Data.SqlClient 。可存取 MS SQL Server 2000、Oracle 8i/9i/10g、MySQL 等資料庫伺服器。 • OLE DB .NET 資料提供者使用原生 OLE DB 啟用資料存取,可存取各種 OLE DB 資料來源,例如 MS Access、OLAP Services、Directory Services 或其他異質資料庫,其命名空間為 System.Data.OleDb
SQL .NET Data Provider VS. OLE DB .NET Data Provider Firebird Oracle MySQL
1 7 - 3 使用對話框連結資料庫 • 在上一節中我們認識了.NET 資料提供者的核心物件, 現在就讓我們來學習如何在C# 的設計階段, 能夠自動產生這些物件, 並且透過這些物件, 只要寫極少的程式, 就可以連結到資料庫。
範例17-3a • MS Access 資料庫的範例檔 Northwind.mdb 中的『客戶』資料表的內容如下, 請利用ADO.NET 提供的物件, 顯示出來。
範例17-3aStep-1 • 新增視窗應用程式專案 • 進入伺服器總管 • 加入資料連線
範例17-3aStep-4 • 將『客戶』資料表拖曳至表單內 • 確認出現下列項目oleDbConnection1oleDbDataAdapter1
範例17-3aStep-5 • 右擊oleDbAdapter1產生資料集
範例17-3aStep-6 • 於表單內配置 DataGrid • 將DataGrid 的 DataSource 設定為 dataSet11.客戶
範例17-3aStep-7 • 於表單 Load 事件中鍵入下列程式碼:oleDbDataAdapter1.Fill(dataSet11);
1 7 - 4 使用程式連結資料庫 • 建立 ConnectionString • 以 ConnectionString 建立 Connection 物件 • 建立 SQL 的 SELECT 敘述 • 以 SQL 敘述與 Connection 物件建立 DataAdapter • 以 CommandBuilder 建立 INSERT、UPDATE、DELETE 敘述 • 以 DataAdapter 填滿 DataTable
連接 SQL Server 的ConnectionString • 要件 • data source 指定資料庫伺服器,可以是資料庫伺服器名稱,也可以是資料庫伺服器的 IP 位址。(local) 指本機的資料庫伺服器。 • user id 登入資料庫的帳號 • password 登入密碼 • initial catalog 資料庫名稱,一個資料庫伺服器上面通常有很多個資料庫,因此必須指定一個 • 範例 data source=(local);user id=sa;password=1234;initial catalog=Northwind
連接 MS Access (OleDB)的ConnectionString • 要件 • Provider 資料提供者(驅動程式) • user id 帳號,若資料庫不需要帳號,則此項可以省略 • password 密碼,如果不需要密碼(密碼為空白)則可以省略此項 • data source 資料庫檔案名稱(包含路徑) • 範例 Provider=Microsoft.Jet.OLEDB.4.0;user id=Admin;data source=Northwind.mdb
選擇資料提供者(Data Provider) • 我們必須要先確定欲連結資料庫的種類, 以選擇適當的.NET 資料提供者。例如, SQL Server 7.0 以上的版本, 要在程式最開始的地方, 加上以下敘述: • using System.Data.SqlClient; • 若要連結OLE DB 資料來源, 像是Access 資料庫, 則要加上以下敘述: • using System.Data.OleDb;
建立 Connection 物件 • 連接 SQL Server • 連接 MS Access using System.Data; using System.Data.SqlClient; ... string cs = "data source=(local);user id=sa;password=;initial catalog=Northwind"; SqlConnection conn = new SqlConnection(cs); using System.Data; using System.Data.OleDb; ... string cs = "Provider=Microsoft.Jet.OLEDB.4.0;data source=C:\\Northwind.mdb"; OleDbConnection conn = new OleDbConnection(cs);
建立 Command 物件 • Command 物件的用途為傳送 SQL 指令 • SQL Server 版 string sql = "SELECT * FROM customers"; SqlCommand cmd = new SqlCommand(sql, conn); SqlCommand cmd = new SqlDbCommand(); cmd.CommandText = "SELECT * FROM customers"; cmd.Connection = conn;
建立 Command 物件 • OleDb版 string sql = "SELECT * FROM customers"; OleDbCommand cmd = new OleDbCommand(sql, conn); OleDbCommand cmd = new OleDbCommand(); cmd.CommandText = "SELECT * FROM customers"; cmd.Connection = conn;
建立 DataAdapter 物件 • 當我們設定SQL 敘述後, 必須藉由建立DataAdapter 物件與Command 物件連結, 並執行 SQL 敘述擷取資料至用戶端 • SQL Server 版 • MS Access 版 SqlDataAdapter da = new SqlDataAdapter(); da.SelectCommand = cmd; OleDbDataAdapter da = new OleDbDataAdapter(); da.SelectCommand = cmd;
建立DataSet 物件 • 當DataAdapter 物件擷取資料至用戶端後, 利用 Fill 方法, 將資料填入DataSet 物件。例如, 我們要從上例的cm 物件, 將『客戶』資料表中的所有紀錄填入DataSet 物件 OleDbDataAdapter da = new OleDbDataAdapter(cmd); DataSet ds = new DataSet(); da.Fill(ds, "客戶");
整套串起來,SQL Server 版 string sql = "SELECT * FROM customers"; string cs = "data source=(local);user id=sa;password=;initial catalog=Northwind"; SqlConnection conn = new SqlConnection(cs); SqlDataAdapter da = new SqlDataAdapter(sql, conn); DataSet ds = new DataSet(); da.Fill(ds);
整套串起來,MS Access 版 string sql = "SELECT * FROM customers"; string cs = "Provider=Microsoft.Jet.OLEDB.4.0;data source=C:\Northwind.mdb"; OleDbConnection conn = new OleDbConnection(cs); OleDbDataAdapter da = new OleDbDataAdapter(sql, conn); DataSet ds = new DataSet(); da.Fill(ds, “客戶”);
建立與連結 DataGrid 物件 • 欲將取得的資料, 藉由表單輸出, 必須先於表單配置DataGrid 物件。其次, 再設定DataSource 屬性, 如以下敘述: dataGrid1.DataSource = ds.Tables["客戶"]; // 將結果顯示至DataGrid 物件
範例17-4a • 使用本節所介紹的程式敘述, 產生ADO.NET 物件, 重做範例17-3a, 並將結果顯示出來。
範例17-4b • 同 17-4a,改從 SQL Server 連接 Northwind 資料庫
資料繫結 DataBinding 類別 • 資料繫結可以讓控制項與資料來源產生繫結, 顯示資料來源的資料。我們在此介紹兩種資料繫結, 分別是單一欄位與多個欄位值的繫結。
單一欄位值的資料繫結 • 有一些控制項(Control), 像是TextBox、CheckBox 、RadioButton 等, 可以與資料來源結合, 用來顯示某一欄位的值
單一欄位值的資料繫結 • 語法 Control.DataBindings.Add("Property", DataSource, "DataMember"); • Property:是控制項的某個屬性。 • DataSource:可以是 DataSet、DataTable 或 DataView。 • DataMember: • 如果 DataSource 是 DataSet, DataMember 就是「資料表.欄位名稱」 • 如果 DataSource 是 DataTable, DataMember 就是「欄位名稱」。 • 例 • txtCustomerId.DataBindings.Add("Text", ds, "客戶.客戶編號");
多個欄位值的資料繫結 • 最常見的控制項為 DataGrid, 可以顯示多個欄位的多筆記錄。 • 例如, 以下敘述將『客戶』資料表的內容, 由DataGrid 元件顯示出來。 DataGrid1.DataSource = ds; // ds 為 DataSet DataGrid1.DataMember = "客戶";
範例17-5a • 將Access 資料庫"C:\CsBook\Northwind.mdb"『客戶』資料表的內容, 利用本節介紹的兩種資料繫結, 顯示出來。
資料的編輯 • 取得特定欄位的資料 • 更改欄位值 string name = (string)ds.Tables["客戶"].Rows[0]["客戶名稱"]; ds.Tables[0].Rows[0]["生日"] = DateTime.Parse("1967/09/14");
資料的編輯 • 以 DataAdapter 的 Update() 方法將更動過的資料寫回資料庫 • 以 DataSet 和 DataTable 的 AcceptChanges() 方法將紀錄的更動狀態清除 • 利用 CommandBuilder 自動建立 InsertCommand、UpdateCommand、DeleteCommand
protected void UpdateData(DataSet ds, string tableName) { string sql = "SELECT * FROM " + tableName; SqlConnection conn = new SqlConnection(ConnectionString); SqlDataAdapter da; SqlCommandBuilder cb; try { da = new SqlDataAdapter(sql, conn); cb = new SqlCommandBuilder(da); conn.Open(); da.Update(ds.Tables[tableName]); ds.Tables[tableName].AcceptChanges(); } catch (Exception ex) { logger.Error(ex.ToString()); } finally { conn.Close(); } }
記錄指標的移動 • 當 DataSource 與控制項產生資料繫結之後, 利用 BindingManagerBase 類別來處理記錄指標。而這個類別主要利用兩個重要的屬性