Home [ADO.NET] SqlDataAdapter的使用
Post
Cancel

[ADO.NET] SqlDataAdapter的使用

SqlDataAdapter概述

  SqlDataAdapter是 DataSet和 SQL Server之間的橋接器,用於擷取和保存資料。 SqlDataAdapter透過對資料來源使用適當的Transact-SQL語句來映射Fill(它可更改DataSet中的資料以符合資料來源中的資料)和Update(它可變更資料來源中的資料以符合DataSet中的資料)來提供這一橋接。當SqlDataAdapter填入 DataSet時,它為傳回的資料建立必要的表和列(如果這些表和列尚不存在)。

我們可以透過以下三種方法來建立SqlDataAdapter物件:

使用方法

1、透過連接字串和查詢語句

1
2
3
4
5
6
string connString ="uid=帳號;pwd=密碼;database=資料庫;server=伺服器";//SQL Server連結字串
string sql = "SELECT * FROM 表名";

SqlDataAdapter da = new SqlDataAdapter(sql,connString);
DataSet ds = new DataSet();//建立DataSet實體
da.Fill(ds,"自訂虛擬表名");//使用DataAdapter的Fill方法(填充),呼叫SELECT指令

這種方法有一個潛在的缺陷。假設應用程式中需要多個SqlDataAdapter對象,用這種方式來建立的話,會導致創建每個SqlDataAdapter時,都同時建立一個新的SqlConnection對象,方法二可以解決這個問題

2.透過查詢語句和SqlConnection物件來創建

1
2
3
4
5
6
7
8
string connString = "uid=帳號;pwd=密碼;database=資料庫;server=伺服器";//SQL Server連結字串
SqlConnection conn = new SqlConnection(connString);

string sql = "SELECT * FROM 表名";

SqlDataAdapter da = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();//建立DataSet實體
da.Fill(ds,"自訂虛擬表名");//使用DataAdapter的Fill方法(填充),呼叫SELECT指令

3.透過SqlCommand物件來創建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string connStrng = "uid=帳號;pwd=密碼;database=資料庫;server=伺服器";//SQL Server連結字串

SqlConnection conn = new SqlConnection (connStrng); //Sql連結類別的實體化
conn.Open ();//開啟資料庫

//使用SqlDataAdapter時沒有必要從Connection.open()打開,
//SqlDataAdapter會自動開啟關閉它。

string sql = "SELECT * FROM 表名"; //要執行的SQL語句
SqlCommand cmd = new SqlCommand(sql,conn);

SqlDataAdapter da = new SqlDataAdapter(cmd); //建立DataAdapter資料配接器實體
DataSet ds = new DataSet();//建立DataSet實體
da.Fill(ds,"自訂虛擬表名");//使用DataAdapter的Fill方法(填充),呼叫SELECT指令

ConnSql.Close ();//關閉資料庫

注意

  如果只需要執行SQL語句或SP,就沒必要用到DataAdapter ,直接用SqlCommand的Execute系列方法就可以了。 sqlDataadapter的作用是實作Dataset和DB之間的橋樑:例如將對DataSet的修改更新到資料庫。

SqlDataAdapter的UpdateCommand的執行機制是:當呼叫SqlDataAdapter.Update()時,檢查DataSet中的所有行,然後對每一個修改過的Row執行SqlDataAdapter.UpdateCommand ,也就是說如果未修改DataSet中的數據,SqlDataAdapter. UpdateCommand不會執行。

使用要點

1.注意開啟和關閉連線的處理

  在呼叫SqlCommand物件執行sql指令之前,需要確保與該物件關聯的SqlConnection物件時開啟的,否則SqlCommand的方法執行時將引發一個異常,但是我們在上面的程式碼中看到,SqlDataAdapter沒有這樣的要求。

  如果呼叫SqlDataAdapter的Fill方法,且其SelectCommand屬性的SqlConnection是關閉狀態,則SqlDataAdapter會自動開啟它,然後提交查詢,取得結果,最後關閉連線。如果在呼叫Fill方法前,SqlConnection是開啟的,則查詢執行完畢後,SqlConnection也會是開啟的,也就是說SqlDataAdapter會保證SqlConnection的狀態恢復到原來的情形。

這有時會導致效能問題,需要注意,例如下面的程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
string connString = "uid=帳號;pwd=密碼;database=資料庫;server=伺服器";//SQL Server連結字串

SqlConnection conn = new SqlConnection(conn);
SqlDataAdapter daCustomers,daOrders;

sql = "SELECT * FROM Customers";
daCustomers = new SqlDataAdapter(sql, conn);

sql = "SELECT * FROM Orders";
daOrders = new SqlDataAdapter(sql, conn);

DataSet ds = new DataSet();
daCustomers.Fill(ds,"Customers"); //呼叫Fill方法 連線被開啟和關閉
daOrders.Fill(ds,"Orders");//呼叫Fill方法, 連線再一次的 被開啟和關閉

以上程式碼會導致連線被開啟和關閉兩次,在呼叫Fill方法時各一次。為了避免開啟和關閉SqlConnection對象,在呼叫SqlDataAdapter物件的Fill方法之前,我們可以先開啟SqlConnection對象,如果希望之後關閉連接,我們可以再呼叫Close方法,就像這樣:

1
2
3
4
5
6
conn.Open(); //連線先打開

daCustomers.Fill(ds,"Customers");
daOrders.Fill(ds,"Orders");

conn.Close(); //關閉連線

2.多次呼叫Fill方法需要注意資料重複和有效更新資料的問題

1
2
3
4
5
6
7
8
9
10
string connString = "uid=帳號;pwd=密碼;database=資料庫;server=伺服器";//SQL Server連結字串
SqlConnection conn = new SqlConnection(conn);

sql = "SELECT * FROM Customers";
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();

da.Fill(ds,"Customers");
//...
da.Fill(ds,"Customers");

我們分析上面的程式碼,透過兩次呼叫Fill方法,SqlDataAdapter執行兩次查詢,並兩次將查詢結果儲存到DataSet中,第一次呼叫在DataSet中建立了一個名為Customers的新表。第二次呼叫Fill方法將查詢的結果追加到DataSet中的同一個表中,因此,每個客戶的資訊將在DataSet中出現兩次!當然,如果資料庫管理員對Customers表定義了主鍵,則SqlDataAdapter在填成DataTable時,會判斷重複行,並自動丟棄掉舊的值。

思考一下,假定一個特定客戶在第一次呼叫Fill方法時,儲存於資料庫中,那麼SqlDataAdapter會將其加入到新建的DataTable中。如果後來這個客戶被刪除了,那麼第二次呼叫Fill方法時,SqlDataAdapter將不會在查詢結果中找到該客戶信息,但是它也不會將客戶資訊從DataSet中刪除。這就導致了數據更新的問題。

所以建議的做法是,在呼叫Fill方法前,先刪除本地DataSet中快取的資料!

MSDN - 從 DataAdapter 填入資料集
MSDN - SqlDataAdapter 類別
MSDN - DataSet 類別
C#中Sql DataAdapter的使用

This post is licensed under CC BY 4.0 by the author.

[ADO.NET] 關於資料庫連接的開啟與關閉(使用SqlDataReader和SqlDataAdapter)

[ADO.NET] DataReader 和 DataAdapter 的區別