ADO.NET - 資料存取的聖石 曹祖聖 台灣微軟資深講師 jimycao@syset.com MCP, MCP+I, MCSA, MCSE, MCDBA, MCAD, MCSD, MCT, MVP
課程大綱 ADO .NET 架構介紹 如何使用 ADO .NET 存取資料庫 ADO 與 ADO .NET 的差異處理 分頁處理技術 離線資料處理機制 XML 支援 ADO .NET 小技巧
.NET Framework 中 ADO 與 XML 架構 使用 VS .NET 整合環境 精靈或程式碼產生 XSL/T, X-Path, etc DataSet XmlData- Document 同步 DataAdapter XmlReader DataReader .NET Data Provider Command Connection
Connection 物件 SqlConnection OleDbConnection Conn.ConnectionString = "User ID=sa; Password=; Server=localhost;Database=Northwind" OleDbConnection Conn.ConnectionString = "Provider=SQLOLEDB; User ID=sa; Password=; Data Source=localhost; Initial Catalog=Northwind" 只能夠連接 Microsoft SQL Server 效能最佳化 需引用 System.Data.SqlClient 可以透過 OLE DB 連接不同的資料庫 應用範圍最廣 需引用 System.Data.OleDb 一樣可以連接 Microsoft SQL Server
如何建立資料庫連線 使用資料庫連線的步驟 Dim Conn As New OleDbConnection() 建立資料庫連線物件 Conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; User ID=Admin; Password=123; Data Source=C:\Northwind.mdb" Conn.Open() Conn.Close() 建立資料庫連線物件 設定連線字串 開啟資料庫連線 : 關閉資料庫連線
如何處理本機 Transaction 處理本機 Transaction 的步驟 Conn.Open() Dim trans As SqlTransaction trans = Conn.BeginTransaction() If … Then trans.Rollback() If … Then trans.Commit() Conn.Close() 啟始一個 Transaction : Transaction 失敗時 Transaction 成功時
ADO RecordSet ADO.NET RecordSet ADO.NET Forward Only Cursors DataReader DataSet Client Cursors Server Cursors XmlDataDocument
Cursors Forward & Read Only Cursor ADO : Forward Only Recordset ADO .NET : DataReader Dim sql As String = "select PName, Qty from MyOrders" Dim cmd As SqlCommand = new SqlCommand(sql, Conn) Dim dr As SqlDataReader = cmd.ExecuteReader() Do While dr.Read() Dim pname As String = dr.GetString(0) Dim qty As Integer = dr.GetInt32(1) Console.WriteLine("{0}, {1}", pname, qty) Loop
多筆資料的瀏覽 DataReader
Server Cursors ADO.NET: ADO 中的 Server cursors 適合用在: 著重在離線資料的存取,適合用在 Internet 上 ADO 中的 Server cursors 適合用在: Client/Server 架構中做資料繫結 單筆資料的修改 OLTP 式的資料存取 (資料鎖定的時間長) 克服同一個 Connection 無法連續執行多個指令 (同一個 Batch) 的限制 DataSet
Server Cursor ADO .NET 的解決方案 單筆資料的修改 使用 DataSet 支援 Transaction 另外使用 Command OLTP 式的資料存取 使用 Command, DataReader, Transaction 最好使用 Stored Procedure 同一個 Connection 連續執行多個指令 使用 Dynamic SQL 語法
Command 物件 SqlCommand 與 OleDbCommand 支援多種 SQL 命令 允許加入參數 (Parameters) DCL : GRANT, REVOKE, DENY DDL : CREATE, ALTER, DROP DML : SELECT, INSERT, DELETE, UPDATE 其它 : Stored Procedure, CURSOR, … 允許加入參數 (Parameters)
單筆資料的修改 ExecuteNonQuery 方法 建立一個 Command 物件 建立參數物件 設定參數值 將參數加入 Command 物件 執行 SQL 語法 Dim cmd As New SqlCommand("update… where OrderID=@ID", Conn) Dim param As New SqlParameter("@ID", TypeOf(Integer)) param.Value = 12 cmd.Parameters.Add(param) Dim rowEffects As Integer = cmd.ExecuteNonQuery()
單筆資料的查詢 ExecuteScalar 方法 建立一個 Command 物件 建立參數物件 設定參數值 將參數加入 Command 物件 執行 Command 並取得結果 Dim sql As String = "select cid from… where OrderID=@ID" Dim cmd As New SqlCommand(sql, Conn) Dim param As New SqlParameter("@ID", TypeOf(Integer)) param.Value = 12 cmd.Parameters.Add(param) Dim myCID As Integer = cmd.ExecuteScalar()
執行 Stored Procedure CommandType.StoredProcedure 設定使用連線 設定命令名稱 設定 CommandType 建立參數 執行 Stored Procedure Dim cmd As New SqlCommand() cmd.Connection = conn cmd.ComandText = "DeleteOrder" cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add("@ID", orderID) Dim rowEffects As Integer = cmd.ExecuteNonQuery()
Web Form 控制項資料繫結 將 Web Form 控制項 DataSource 屬性繫結到 DataReader 物件 如果控制項一次只能顯示資料表中的單一欄位,則除了 DataSource 屬性之外,還要加設 DataTextField 和 DataValueField 屬性 最後一定要執行控制項的 DataBind 方法,將資料取回控制項中,進行繫結
Stored Procedure Web Form Data Binding
SQL 分頁查詢技巧 DECLARE mycursor SCROLL CURSOR FOR SELECT * FROM Customers OPEN mycursor DECLARE @loc int SET @loc = @page * @pagesize + 1 FETCH ABSOLUTE @loc FROM mycursor DECLARE @no int SET @no = @pagesize – 1 WHILE @@FETCH_STATUS = 0 AND @no > 0 BEGIN FETCH NEXT FROM mycursor SET @no = @no - 1 END CLOSE mycursor DEALLOCATE mycursor
SQL 分頁查詢技巧
Dynamic SQL 同一個 Connection 連續執行多個指令 cmd.CommandText = "DECLARE mycursor SCROLLABLE CURSOR FOR SELECT * FROM Customers" ; cmd.ExecuteNonQuery(); cmd.CommandText = "OPEN mycursor" ; cmd.CommandText = "FETCH NEXT FROM mycursor" ; SqlDataReader dr =cmd.ExecuteReader(); // 讀取並處理資料 dr.Close(); cmd.CommandText = "FETCH ABSOLUTE 5 FROM mycursor" ; cmd.CommandText = "UPDATE Customers set ContactName = 'Luca Bolognese' WHERE CURRENT OF mycursor" ; cmd.CommandText = "CLOSE mycursor; DEALLOCATE mycursor" ;
Recordset .NET 透過 Dynamic SQL 與 SQL Cursor 技術實作 Recordset .NET 支援 LockType : Optimistic, Pessimistic, ReadOnly CursorType : Dynamic, Static, Keyset, ForwardOnly Recordset 移動: MoveNext, MoveLast, … 分頁: PageSize, AbsolutePage CursorLocation Server : 直接使用 SQL 的 CURSOR Client : 物件中自行記錄並處理記錄指標
Recordset .NET Dim RS As New Recordset() RS.PageSize = 5 RS.AbsolutePage = 3 RS.Open("SELECT * FROM Customers", "Server=127.0.0.1;Database=Northwind") Dim No As Integer = RS.PageSize Do While Not RS.EOF And No > 0 Console.WriteLine("{0}\t{1}", RS(0), RS("CompanyName")) RS.MoveNext() No = No - 1 Loop RS.Close()
Dynamic SQL 伺服器端分頁技術 Recordset.NET
如何使用舊版 ADO ADO 2.x 版的解決方案 舊版 ADO Data Provider 依舊可以使用 自行引用下列空間,並撰寫程式碼 ADODB Microsoft.VisualBasic.Compatibility.VB6 MSAdodcLib MSDATASRC Stdole 建議使用升級精靈
VB 升級精靈
離線資料的存取 DataAdapter 與 DataSet 的關係 如何取得 DataSet DataSet 的結構 WinForms 控制項資料繫結的方式
DataAdapter 與 DataSet DataSet 與資料庫之間透過 DataAdapter 進行存取動作 DataAdapter SelectCommand InsertCommand UpdateCommand DeleteCommand Fill DataSet 資 料 庫 Update
如何取得 DataSet 透過 DataAdapter 取得 DataSet 資料 Dim cmd As New SqlCommand() cmd.Connection = Conn cmd.ComandText = "select * from Customers" Dim da As New SqlDataAdapter() da.SelectCommand = cmd Dim ds As New DataSet("Customers") da.Fill(ds) Dim da As New SqlDataAdapter( "select * from Customers", Conn ) 建立一個 Command 用來執行 SELECT 語法 建立 DataAdapter 物件 設定 SelectCommand 建立一個 DataSet 物件 使用 DataAdapter 物件的 Fill 方法 填滿 DataSet
DataSet 的結構 使用 Tables(表格號碼) 或 Tables("表格名稱") 來引用 Tables 中的任何一個表格。 (Tables.Count 可以取得表格數目) 每一個 DataSet 中的表格都是一個 DataTable 物件 DataTable 可以包含多筆資料列 (Row),組成 Rows 集合 使用 Rows(列號碼) 來引用 Tables 中的任何一個表格。 (Rows.Count 可以取得資料總筆數) 透過欄位號碼或欄位名稱來存取 DataRow 的資料 每一個 DataRow (每一筆記錄) 中包含了多個欄位 DataSet 可以包含多個表格 (Table),組成 Tables 集合 Rows 集合中的每一筆資料記錄都是一個 DataRow 物件 DataSet Tables DataTable Tables(0) Tables(1) Tables(2) Tables(3) : DataRow Rows Rows(0) Rows(1) Rows(2) : AB (04)2222-2222 男 王小明 血型 電話 性別 姓名 3 2 1 Dim row As DataRow = ds.Tables(0).Rows(3) Dim name As String = row(0) Dim phone As String = row("電話")
如何瀏覽 DataSet 中的資料 使用 For Each 迴圈瀏覽 DataSet 資料 Dim cust, ord As DataRow For Each cust In ds.Tables(0).Rows Console.WriteLine( "\n客戶: {0}", cust("Name") ) For Each ord In cust.GetChildRows("odr") Console.Write( "訂單編號: {0}", ord("id") ) Console.Write( "\t數量:{1}\n", ord("qty") ) Next Next 使用 For 迴圈瀏覽 DataSet 資料 For c = 0 To ds.Tables(0).Columns.Count - 1 Dim dc As DataColumn = ds.Tables(0).Columns(c) Console.Write("{0}\t", dc.ColumnName) Next For r = 0 To ds.Tables(0).Rows.Count - 1 cName = ds.Tables(0).Rows(r)("客戶名稱") cAddress = ds.Tables(0).Rows(r)("地址") Console.WriteLine("\n{0}\t{1}", cName, cAddress) Next
DataList + DataSet
如何將 DataSet 中的資料 更新至資料庫 Dim adapter As New SqlDataAdapter() Dim delete As New SqlCommand("DeleteOrder",cnn) delete.CommandType=CommandType.StoredProcedure delete.Parameters.Add("@OrderID", Typeof(Integer)).SourceColumn="OrderID" adapter.DeleteCommand = delete Dim insert As New SqlCommand("AddOrder",cnn) insert.CommandType=CommandType.StoredProcedure insert.Parameters.Add("@OrderID", TypeOf(Integer)).SourceColumn="OrderID" insert.Parameters.Add("@CustD", TypeOf(Integer)).SourceColumn="CustomerID" insert.Parameters.Add("@Date", TypeOf(DateTime)).Value = DateTime.Now adapter.InsertCommand = insert Dim update As New SqlCommand("UpdateOrder",cnn) update.CommandType=CommandType.StoredProcedure update.Parameters.Add("@OrderID", TypeOf(Integer)).SourceColumn="OrderID" update.Parameters.Add("@CustD", TypeOf(Integer)).SourceColumn="CustomerID" adapter.UpdateCommand = update adapter.Update(ordersTable) Dim da As = New SqlDataAdapter ("select * from Customers", conn) : : Dim cb As New SqlCommandBuilder(da) da.InsertCommand = cb.GetInsertCommand da.UpdateCommand = cb.GetUpdateCommand da.DeleteCommand = cb.GetDeleteCommand da.Update(ds)
Win Form 控制項資料繫結 指定將 DataSet 中的 Members.Name 欄位繫結到 Text 屬性 指定將 DataSet 中的 Members.Size 欄位繫結到 Width 屬性 繫結到 txtName 文字方塊 使用 Binding 物件進行資料繫結 控制項的任何屬性都可以繫結到資料庫的 任何欄位,可且可以繫結多個屬性 Dim bdText As New Binding("Text", ds, "Members.Name") Dim bdWidth As New Binding("Width", ds, "Members.Size") txtName.DataBindings.Add(bdText) txtName.DataBindings.Add(bdWidth)
CurrencyManager 用來控制 Binding 的相關動作 Dim cm As CurrencyManager cm = BindingContext(ds, “Customers") cm.Position = 0 ‘ 第一筆 cm.Position = cm.Position + 1 ‘ 下一筆 cm.Position = cm.Count – 1 ‘ 移到最後一筆 cm.AddNew() ‘ 新增一筆 cm.EndCurrentEdit() ‘ 結束編輯 cm.RemoveAt( cm.Position ) ‘ 刪除一筆
DataBinding BindingManager
前端 DataSet 資料表關聯 DataSet 中各 DataTable 之間可以建立關聯性 Dim dr As New DataRelation( “關聯名稱” , Primary Key / Parent 欄位 , Foreign Key / Child 欄位 ) DataSet 中各 DataTable 之間可以建立關聯性 Primary Key Parent Column Foreign Key Child Column DataRelation 物件與 Relations 集合 Dim dr As New DataRelation( "CustomerToOrders" , ds.Tables(“Customers").Columns(“CustomerID") , ds.Tables("Orders").Columns(“CustomerID") ) ds.Relations.Add(dr)
GetChildRows 方法 透過 DataSet 中 Parent 表格中每一筆資料 DataRow 的 GetChildRows 方法,可以取得所關聯的 Child 表格中的資料。 Dim dr As DataRow = ds.Tables(“Customers").Rows(0) Dim child() As DataRow = dr.GetChildRows(“CustomerToOrders") For I = 0 To child.Length - 1 Dim pid As Integer = child( I )( "ProductID" ) Dim qty As Integer = child( I )( "Quantity" ) Console.Write("{0}\t{1}\n", pid, qty) Next
DataRelation
ADO .NET 與 XML XSL/T, X-Path, etc DataSet XmlData- Document XmlReader 同步 DataAdapter XmlReader DataReader .NET Data Provider Command Connection
ADO .NET 與 XML DataSet, DataReader XmlDataDocument 資料 Schema 將 DataSet 中的資料輸出成 XML 文件 Schema 由 XSD 或 XML 文件讀入 Schema 將 DataSet 的 Schema 輸出至 XSD 文件 XmlDataDocument 與 DataSet 直接對應 使用 XmlReader 與 XmlWriter 直接存取 XML 文件資料
如何存取 XML 文件 透過 ReadXml 與 WriteXml 存取 XML 文件 DataSet ds = new DataSet() ds.ReadXml("food.xml") DataRow row = ds.Tables(0).NewRow() row("FoodID") = 10 row("FoodName") = "可樂" ds.Tables(0).Rows.Add(row) ds.WriteXml("food.xml") 建立一個 DataSet 物件 使用 ReadXml 方法讀取 XML 文件 在 DataSet 中新增一筆資料 : 使用 WriteXml 方法輸出 XML 文件
ReadXml WriteXml
SQL Server 2000 對 XML 的支援 以 XML 格式查詢資料庫 直接以 XML 格式傳回 SELECT 結果 一次取回關聯式與階層式資料 FOR XML AUTO / FOR XML RAW 使用 ReadXml 方法將資料放入 DataSet 使用 XmlReadMode.Fragement 參數 使用 Diffgrams 格式傳遞 XML 資料 SQL Server 2000 支援 DataSet Diffgrams 格式的 XML 文件
如何使用 SQL Server 的 XML 功能 // 或者載入 DataSet DataSet ds = new DataSet() ; ds.ReadXml(xr, XmlReadMode.Fragment) ; Dim cmd As SqlCommand = new SqlCommand( "Select * from authors FOR XML AUTO, ELEMENTS", Conn) ; Dim xr As XmlReader = cmd.ExecuteXmlReader() ‘ 直接讀取 If xr.Read() Then Dim s As String = xr.ReadOuterXml() Do While s <> "" Response.Write(s + vbCrLf) s = xr.ReadOuterXml() Loop End If
SQL XML
將 XML 文件載入 DataSet 只保留必要部份 如果要完整保留 XML 文件,請使用 XmlDataDocument 物件 順序可能會改變 空白不會保留 沒有對應到 DataSet Schema 的 XML 元素或屬性資料會遺失 如果要完整保留 XML 文件,請使用 XmlDataDocument 物件
XmlDataDocument 一個 DataSet 對應一個 XmlDataDocument 根據 DataSet 中的 Schema 定義 (DataRelation) 允許控制項資料繫結、關聯式存取 XML 資料、嚴格型別檢查 允許使用 XML 工具 (Schema 檢查、XSL/T、XPath 查詢) 針對關聯式資料進行處理 完整保留 XML 文件或 DataSet 的內容
XML 與 XSL/T XSL/T XSL/T
XML 與 XSL/T <?xml version="1.0" encoding="big5" ?> <?xml-stylesheet type="text/xsl" href="show1.xslt" ?> <StudentsTable> <Student No="11"> <Name>王小明</Name> <Address>台中市中區中山路27號5樓</Address> <Phone>04-22210973</Phone> </Student> <Student No="12"> <Name>陳水果</Name> <Address>台北市南京東路二段12號</Address> <Phone>02-22223332</Phone> <Student No="13"> <Name>李國家</Name> <Address>台南縣官田鄉水果路27號</Address> <Phone>07-33322112</Phone> </StudentsTable>
XML 與 XSL/T <?xml version="1.0" encoding="utf-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <TABLE BORDER="1"> <TR> <TD>編號</TD><TD>姓名</TD> <TD>地址</TD><TD>電話</TD> </TR> <xsl:for-each select="//Student"> <TD><xsl:value-of select="@No" /></TD> <TD><xsl:value-of select="Name" /></TD> <TD><xsl:value-of select="Address" /></TD> <TD><xsl:value-of select="Phone" /></TD> </xsl:for-each> </TABLE> </xsl:template> </xsl:stylesheet>
XSL/T XSL/T XSL/T
使用 X/Path 處理 DataSet 資料 建立一個 XmlDataDocument 物件對應到 DataSet 使用 X/Path 查詢出 XML 節點 針對查詢結果,進行處理 使用 GetRowFromElement 方法從 XML 文件中取得 DataRow,並進行處理 Dim xd As XmlDataDocument = New XmlDataDocument(ds) Dim nodes As XmlNodeList = xd.SelectNodes("//Student[@No<11]") For Each node As XmlNode In nodes Dim row As DataRow = xd.GetRowFromElement(node) row.Delete() Next
使用 XSL/T 輸出 DataSet 資料 Dim xsl As XslTransform = New XslTransform() 轉換 XmlDataDocument 讀取轉換後的結果 Dim xsl As XslTransform = New XslTransform() xsl.Load("show.xslt") Dim xr As XmlReader = xsl.Transform(xd, Nothing) Do While xr.Read() Response.Write(xr.ReadOuterXml()) ; Loop
資 料 庫 XmlDataDocument XmlDataDocument XSL/T XSL/T
ADO .NET 十大技巧
如何在設計時期指定 Metadata 狀況: 為了取得 Metadata 資料,必須往返資料庫 ,降低執行效率 DataReader : 嚴格型別的資料讀取方式 DataSet 載入資料,但是不要載入 Schema 指定適當的 XmlReadMode XmlReadMode.IgnoreSchema Data Adapter 用程式指定 INSERT / UPDATE / DELETE commands 用程式指定 Command 的參數 避免使用 CommandBuilder 指定 Primary Key
如何更新資料至 DataSet ? 狀況: 資料庫中的資料可能有變動,希望 將最新的資料更新到 DataSet 中 解決方式: 使用 Adapter.Fill() 方法 會蓋掉 DataSet 中原本已修改的資料 我想要取得資料庫中最新的資料,但是也想要保留 DataSet 中已修改部份 Dim newDs As New DataSet() da.Fill(newDs) ds.Merge(newDs, true)
如何撰寫支援任何一種 .NET Data Provider 的程式 狀況: 針對 OleDb, Sql, Odbc … 等 .NET Data Providers,所需的相關物件 都不同,例如 Command, DataAdapter, … 解決方式: 使用 IDbConnection 介面 使用 IDbConnnection 的 CreateCommand() 方法取得 IDbCommand 自訂 Data Provider
支援多種 .NET Data Providers
如何一次讀取多表格至 DataSet ? 狀況: 希望一次讀取多個表格至 DataSet 解決方式: 使用批次 SQL 查詢或執行 Stored Procedure Dim da As New SqlDataAdapter( "SELECT * FROM customers; SELECT * FROM orders", Conn) da.Fill(ds) 使用 ExecuteXmlReader 讀取 SQL Server 傳回 的 XML Dim cmd As New SqlCommand( "SELECT Customers.*, Orders.* FROM Customers, Orders " & "WHERE Customer.State='CA' AND " & "Customer.CustID=Order.CustID FOR XML AUTO", Conn) Dim xr As XmlReader = cmd.ExecuteXmlReader() ds.ReadXml(xr, XmlReadMode.Fragment)
如何對應 DataAdapter 所傳回來的 DataSet 中每一個表格的名字 ? 狀況: 當多個表格由 DataAdapter 傳回 DataSet 時 ,預設的表格名字是 "Table1", "Table2", … 解決方式: Dim da As New SqlDataAdapter( "SELECT * FROM customers; SELECT * FROM orders", Conn) da.TableMappings.Add("Table1", "客戶資料") da.TableMappings.Add("Table2", "訂單資料") da.Fill(ds)
如何傳遞 Null 值給 Command 的 Parameter ? 狀況: 無法使用 null, Nothing, "" 當做 Null 值 傳至 Command 的 Parameter,不傳值 也不行 !! 解決方式: 使用 DBNull.Value Dim param As New SqlParameter() param.Value = DBNull.Value
如何避免 DataReader 自動預讀資料 ? 解決方式: Dim cmd As New SqlCommand("Select * from Employees ", Conn) Dim dr As DataReader = cmd.ExecuteReader (CommandBehavior.SequentialAccess) Do While dr.Read() // 依序讀取每一個欄位 For I = 0 To dr.FieldCount – 1 Console.Write( "\t {0}", dr( I ) ) Next Console.WriteLine() Loop
如何在關閉 DataReader 時自動 關閉對應的 Connection ? 解決方式: Private Function GetCategories() As DataReader Dim cmd As New SqlCommand ("Select * from Categories", Conn) Dim dr As DataReader = cmd.ExecuteReader (CommandBehavior.CloseConnection) Return dr End Function
如何處理新增資料時,不同用戶端 Primary Key 衝突的問題 ? 狀況: 不同用戶端可能產生同樣的 Primay Key 欄位值,在新增至 DataSet 或 資料庫時,就會產生錯誤 解決方式: 使用 GUID 格式的 Primary Key 欄位 用戶端可以自行產生 保證不會重覆 更新至資料庫時,不需要修改 Primary Key 值 關聯的子表格 Foreign Key 欄位也不需要修改 Primary Key 欄位長度比較長 (128 bits)
如何新增包含自動編號限制的 Primary Key 的資料 ? 狀況: 由於 DataSet 中針對自動編號欄位,預設 由 0 開始累加,每次加一,然而常常與 原本 DataSet 中已存在的資料相衝突 !! 解決方式: Dim cmd As New SqlCommand( _ "SELECT TOP 1 ( ID + 1 ) AS ID FROM Members " & _ "ORDER BY ID DESC", Conn) Dim dr As SqlDataReader = cmd.ExecuteReader() If dr.Read() Then ds.Tables(0).Columns(0).AutoIncrementSeed = dr.GetInt32(0) End If
將含有自動編號的資料新增至資料庫 Sub da_RowUpdating(sender As Object, e As SqlRowUpdatingEventArgs) If e.StatementType = StatementType.Insert Then e.Status = UpdateStatus.SkipCurrentRow conn.Open() da.InsertCommand.CommandText += ";select @@identity as ID" SqlDataReader dr = da.InsertCommand.ExecuteReader() If dr.Read() Then e.Row( "ID" ) = dr.GetValue(0) End If dr.Close() conn.Close() End Sub
處理自動編號欄位
總結 ADO.NET… 提供程式開發人員超強的資料存取機制 支援舊版 ADO 先進的資料存取物件 開放式架構 提供完善的升級精靈 .NET Data Providers 提供各類型資料庫的連結 DataSet 支援離線資料的存取 開放式架構 可以在設計時期進行 DataSet Schema 的存取 支援舊版 ADO 提供完善的升級精靈 提供舊版資料繫結的解決方案
相關資訊 MSDN http://www.microsoft.com/taiwan/msdn 技術白皮書 ADO.NET for the ADO Programmer: http://msdn.microsoft.com/library/en-us /dndotnet/html/ADONETProg.asp ADO.NET Best Practices: http://msdn.microsoft.com/library/en-us /dndotnet/html/ADONETBest.asp The .NET Show: ADO.NET: http://msdn.microsoft.com/theshow /Episode017/default.asp