轉自:http://www.cnblogs.com/yangcaogui/archive/2012/06/09/2537086.htmlhtml
目錄:ajax
一丶簡單的介紹下ADO.NETsql
瞭解System.Data命名空間下咱們經常使用的一些類:數據庫
1 ①System.Data → DataTable,DataSet,DataRow,DataColumn,DataRelation,Constraint,DataColumnMapping,DataTableMapping 2 ②System.Data.Coummon → 各類數據訪問類的基類和接口 3 ③System.Data.SqlClient → 對Sql Server進行操做的數據訪問類 4 主要有: a) SqlConnection → 數據庫鏈接器 5 b) SqlCommand → 數據庫命名對象 6 c) SqlCommandBuilder → 生存SQL命令 7 d) SqlDataReader → 數據讀取器 8 e) SqlDataAdapter → 數據適配器,填充DataSet 9 f) SqlParameter → 爲存儲過程定義參數 10 g) SqlTransaction → 數據庫事物
二丶SqlConnection(鏈接對象)數組
1.鏈接字符串緩存
基本語法:數據源(Data Source)+數據庫名稱(Initial Catalog)+用戶名(User ID)+密碼(Password)(這種方式比較安全)!安全
推薦文章 :SQL Server 鏈接字符串和身份驗證,你必須知道的ADO.NET(三) 鏈接字符串,你小覷了嗎?,SQL Server 2008鏈接字符串寫法大全,鏈接字符串有不少的寫法,最保險的寫法能夠藉助「SqlConnectionStringBuilder」類,它提供了全面的鏈接字符串的屬性,以致於減小出錯率(相關屬性查MSDN),還有大多數鏈接字符串都寫在配置文件裏面了!app
2.建立鏈接對象ide
3.打開和關閉鏈接對象(使用Using來關閉鏈接)函數
關於鏈接池的文章:你必須知道的ADO.NET(五) 細說數據庫鏈接池(寫的還真不賴啊),頂...
三丶SqlCommand(命令對象)
1.實例化的時候默認初始化的四個屬性
2.建立命令對象
使用鏈接對象的「CreateCommand()」方法建立命令對象,也可使用new來實例化對象!
1 SqlCommand command = connection.CreateCommand(); //這種方式比較好,也能夠本身實例化一個對象!
3.幾個重要屬性
①CommandText:獲取或設置要對數據源執行的 Transact-SQL 語句、表名或存儲過程!
②CommandType:設置你執行的SQL語句是存儲過程仍是T-SQL(是一個枚舉)!
③Parameters:設置你T-SQL中你須要用到的參數(後面會講到),是一個「SqlParametersCollection」類型,這個屬性很重要,是你經過代碼給SQL語句傳遞參數的途徑,因此記住語法,記住一些使用規則講對編碼有很大的幫助!
4.幾個重要的方法(相信你們熟悉的不能再熟悉了)
①ExecuteNonQuery:返回是影響的行數(int),主要執行更新,添加,刪除等操做!
②ExecuteReader:執行SQL或存儲過程,返回的是SqlDataReader類型,主要用來查詢!
★ 這邊注意這個方法的重載 CommandBehaviour 枚舉,成員以下:
1 command.ExecuteReader(CommandBehavior.CloseConnection); //在執行讀取以後會自動關閉鏈接對象
③ExecuteScalar:返回執行結果集中的第一行第一列,若是沒有數據,則返回NULL!
Note:由於可能會返回「Null」值,因此須要對結果進行判斷,以下:
④CreateParameter:建立SqlParameter實例
1 SqlParameter para = cmd.CreateParameter() //此方法適合SQL語句中只有一個參數的狀況!
推薦文章:你必須知道的ADO.NET(六) 談談Command對象與數據檢索
你必須知道的ADO.NET(七) Wow!Command對象高級應用
四丶SqlParameter(Sql參數)
1.幾個重要的屬性
ParameterName: 設置參數名
Value: 給參數設置值
Size: 設置參數字節最大大小(以字節爲但爲)
SqlDbType: 參數在SQL中的類型
2.命令對象添加參數集合的幾種方法
①AddWithValue
②Add
③AddRange
推薦文章:SqlParameter的做用與用法,代碼以下:
1 using (SqlConnection connection = new SqlConnection("")) 2 { 3 SqlCommand command = connection.CreateCommand(); 4 command.CommandText = ""; 5 6 //可使用這種方式添加多個參數,不過方式不夠好 7 command.Parameters.Add("@name", SqlDbType.NVarChar).Value = "yang"; //第一種方式 8 command.Parameters.Add("@age", SqlDbType.Int).Value = 888; 9 command.Parameters.Add("@address", SqlDbType.NVarChar, 100).Value = "Jiang Su"; 10 11 //這種方式直接給定參數名和參數就能夠了,可操做性比較差 12 command.Parameters.AddWithValue("@name", "yang"); 13 command.Parameters.AddWithValue("@age", 888).SqlDbType = SqlDbType.Int; 14 command.Parameters.AddWithValue("@address", "Jiang su").SqlDbType = SqlDbType.NVarChar; 15 16 //直接使用參數集合添加你須要的參數,推薦這種寫法 17 SqlParameter[] parameters = new SqlParameter[] 18 { 19 new SqlParameter("@name",SqlDbType.NVarChar,100){Value = "yang"}, 20 new SqlParameter("@age",SqlDbType.Int,2){Value = 888}, 21 new SqlParameter("@address",SqlDbType.NVarChar,20){Value = "Jiang Su"}, 22 }; 23 command.Parameters.AddRange(parameters); //參數也能夠是一個Array數組,若是採用數組參數代碼的可讀性和擴展性就不是那麼好了 24 25 //當咱們把參數都添加好以後,會生成一個「SqlParameterCollection」集合類型,至關於參數的集合 26 //那麼咱們就能夠對這些參數進行修改和移除了 27 //說穿了「SqlParameterCollection」內部實際上是一個List<SqlParameter>的集合,只是它裏面的複雜度比較高,考慮的很全面 28 command.Parameters[0].Value = "hot girl"; 29 command.Parameters[0].Size = 200; 30 }
3.說說「SqlParameterCollection」,參數集合
上面添加的「SqlParameter」參數都被添加到了「SqlParameterCollection」集合中去了,因此咱們纔可以對它進行讀取和修改!
4.定義適當的參數屬性獲取存儲過程的返回值(return) → Direction = ParameterDirection.Output
代碼以下:
五丶SqlDataReader(數據流讀取器)
說實話,若是單單知道怎麼使用讀取器,那是很是好學的,若是深刻了解,它裏面的知識將會很是的吸引人,那麼就以我小菜的經驗來講說把,各位不要見怪啊!
1.基本用法
2.經常使用方法
①GetOrdinal:獲取指定列名的列序號(索引號),使用這個方法能夠把常常變更的列進行固定
1 int name = dr.GetOrdinal("name"); //經過列名來獲取當前列的索引號,這樣若是下次你列名順序發生變化也沒有關係
②GetName: 獲取列名,參數爲指定列名的序列號,返回string
1 string columnName = dr.GetName(name); //經過列名所處的索引號來獲取列名名稱
③IsDBNull:判斷當前讀取的數據是否爲Null,返回類型爲Bool
1 dr.IsDBNull(coContactID) ? "NULL" : dr.GetInt32(coContactID).ToString() //相信你們都會使用的
④NextResult:當查詢爲批處理查詢時,使用這個方法去讀取下一個結果集,返回值爲Bool,若是存在多個結果集,則爲 true;不然爲 false
1 //select * from Employee;select * from County,這樣的話就能夠採用這種方式 2 dr.NextResult(); //記住這個要放在while(dr.Read())以後,由於讀取一個數據集以後才能讀取下一個數據集
⑤Read:讀取數據
讀取數據最重要的方法,不說了!
3.經常使用屬性
①HasRow:判斷是否包含一行或多行,也就是判斷有沒有數據,返回類型爲Bool
②FieldCount:獲取讀取的列數,返回類型爲Int
③IsClosed:判斷讀取的數據流是否關閉
因此靈活運用上面的屬性講加強代碼的可讀性和健壯性,綜合示例:
Note:當 SqlDataReader 關閉後,只能調用 IsClosed 和 RecordsAffected 屬性,若是調用其它方法或屬性將會報錯!
4.性能深刻剖析
讀取數據的時候會有不少種寫法,如 dr[0].ToString(),dr["Name"].ToString(),dr.GetString(0),dr.GetSqlString(0) 等等的讀取方式的寫法,若是你們去網上查資料就會很容易發現這幾種寫法存在着一些差別!
下面是讀取數據性能的總結:
1 SqlDataReader讀取方法: 2 1. DataReader 索引 + 基於 [序列號] → dr[0].ToString | Index-based access 3 2. DataReader 索引 + 基於 [列名] → dr["Name"].ToString | 性能最差 4 3. Get 開頭的 + 基於 [序列號] → dr.GetString(0) | type-access 5 4. GetSql 開頭的 + 基於 [序列號] → dr.GetSqlString(0) | Provider-specific typed accessor 6 5. GetOrdinal() 經過列名獲取這個列的序列號 | 這個方法在提升性能上面有做用 7 6. 性能(4) --> (3) --> (1) --> (2)
Note:因此在對數據進行讀取時要有針對的使用一些性能高的方法,也不是說要追求性能,只是這是一種習慣,對於大多數讀取數據庫的方法使用索引來讀取無疑是最快,記住一句話,「當性能沒有成爲問題的時候,不要過分的去優化它」,高效而又優美的使用這些方法,纔是王道!
PS:我這裏的總結實際上是之前在園子看到一我的寫的,找了半個小時都沒找到,若是有人看到過,發個連接給我,我補上!
5.SqlDataReader和DataSet的討論
推薦文章:談談Asp.net網站優化一:SqlDataReader和DataSet的選擇
六丶SqlTransaction(事務)
1.代碼中的事務
如今代碼中基本使用存儲過程來控制事務的處理,經過代碼進行控制事務也是咱們學習ADO.NET的任務之一!
事務是在鏈接對象以後建立,並把它跟命令對象進行關聯,使用try.....Catch捕獲異常,而後調用RollBack方法回滾事務!
Commit:提交
RollBack:回滾
2.事務中的命名存儲點
一旦你定義了命名存儲點,只能回滾命名存儲點以後的操做,這是要是狀況而使用!
這種狀況是當你調用RollBack方法並重載一個命名存儲點的參數,以下代碼所示:
1 using (SqlConnection conn = new SqlConnection(str)) 2 { 3 conn.Open(); 4 SqlTransaction transaction = conn.BeginTransaction(); 5 SqlCommand cmd = conn.CreateCommand(); 6 cmd.CommandText = ""; 7 cmd.Transaction = transaction; 8 //使用命名存儲點 9 transaction.Save("this is point"); //定義命名存儲點,使用Save方法先保存存儲點,定義回滾數據的開始位置 10 11 //這邊是你要回滾的操做代碼,TO DO... 12 13 //把從命名存儲點到這裏的操做進行回滾 14 transaction.Rollback("this is point"); //回滾命名存儲點 15 }
3.SQL語句中的事務(SQL Server中的事務其實很複雜的)
1 BEGIN TRANSACTION 2 3 --你須要執行的更新,刪除,插入的語句 4 5 IF(@@ERROR > 0) //這是系統變量,存儲你在執行更新,刪除,插入操做時發生錯誤的記錄編號 6 ROLLBACK 7 ELSE 8 COMMIT
推薦文章:淺談SQL SERVER中事務的ACID
4.說說「TransactionScope」,讓事務更加的簡單
1 using (TransactionScope transactionScope = new TransactionScope()) 2 { 3 try 4 { 5 using (SqlConnection connection = new SqlConnection()) 6 { 7 // TO DO 8 //提交事務,若是有異常,他會自動回滾的 9 transactionScope.Complete(); 10 } 11 } 12 catch (Exception) 13 { 14 //捕獲異常 15 throw; 16 } 17 }
推薦文章:C#綜合揭祕——細說事務
七丶SqlDataAdapter(數據適配器)
1.構造函數
1 四個重載: 2 1. 無參 3 2. SqlDataAdapter(SqlCommand) → 執行命令對象實例 4 3. SqlDataAdapter(String, SqlConnection) → ①只能指定查詢語句 ②鏈接對象實例 5 4. SqlDataAdapter(String, ConnectionString) → 用 SelectCommand 和一個鏈接字符串初始化 SqlDataAdapter 類的一個新實例 6 Note:第四個重載就把鏈接對象和命令對象都包含進去了!
2.填充數據(Fill)
最簡單的填充數據
1 DataSet dataSet = new DataSet(); 2 using (SqlConnection conn = new SqlConnection("")) 3 { 4 conn.Open(); 5 SqlCommand command = conn.CreateCommand(); 6 command.CommandText = "select name,age,address from MyInformation"; 7 SqlDataAdapter dataAdapter = new SqlDataAdapter(command); 8 dataAdapter.Fill(dataSet); //填充數據 9 }
3.使用「SqlCommandBuilder」對數據進行增刪改查
①添加數據
1 using (SqlConnection conn = new SqlConnection(ConnectionString())) 2 { 3 conn.Open(); 4 //構建查詢語句,也能夠指定SqlCommand,其中變換的方法有不少 5 SqlDataAdapter da = new SqlDataAdapter("select LastName,FirstName from dbo.Employees", conn); 6 DataSet ds = new DataSet(); 7 da.Fill(ds); 8 //這句話很重要,它會把你在DataSet增長的數據轉化爲SQL語句用來更新數據庫 9 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da); 10 //添加行,實例化一個行對象,注意是用NewRow來建立行 11 DataRow row = ds.Tables[0].NewRow(); 12 row[0] = "Yang"; 13 row[1] = "鬼頭"; 14 ds.Tables[0].Rows.Add(row); //添加到表中 15 da.Update(ds); //把DataSet中表和數據庫進行對比,更新 16 }
②修改數據
1 using (SqlConnection conn = new SqlConnection("")) 2 { 3 SqlDataAdapter da = new SqlDataAdapter("SQL語句或你本身定義的命令對象", conn); 4 DataSet ds = new DataSet(); 5 da.Fill(ds); 6 //很重要的一句話 7 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da); 8 ds.Tables[0].Rows[12][1] = ""; //修改數據 9 da.Update(ds); 10 //調用Update方法其中隱式的調用了AcceptChanges方法,更新數據集中的數據 11 //若是你繼續使用這個數據集而沒有調用這個方法,在後面的使用會出現異常 12 ds.AcceptChanges(); //這句話能夠不寫的 13 }
③刪除數據
1 using (SqlConnection conn = new SqlConnection("")) 2 { 3 SqlDataAdapter da = new SqlDataAdapter("SQL語句或你本身定義的命令對象", conn); 4 DataSet ds = new DataSet(); 5 da.Fill(ds); 6 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da); 7 //刪除數據 8 ds.Tables[0].Rows[12].Delete(); 9 da.Update(ds); //這邊會隱式調用DataTable的AcceptChanges方法 10 }
Note(很重要的注意點): 值得注意的是Update方法已經隱式幫我調用了AcceptChanges,不比擔憂狀態爲改變刪除數據會報錯,微軟已經幫咱們都作好了,其實背後就是 作的Table.AcceptChanges()這件事,若是在通常的DataTable中會怎麼樣,提交自上次調用 AcceptChanges 以來對該行進行的全部更改,在調用這個方法以後,表中全部更改將會提交,全部行狀態(RowState)狀態都將變爲Unchanged,在DataSet中我將會說到這些內容!
4.關於「SqlDataAdapter」中Fill方法的一些討論
簡單的寫一下,MSDN上都有的,查一下就知道了!
1 ★指定填充數據的數量,如: 2 //從第五行到第十行數據填充DataSet 3 //上面的定義錯了 4 //應該是從第六行開始,後面的十條記錄 5 da.Fill(ds,5,10,」MyTable」)
八丶DataSet,DataTable,DataRow,DataColumn
表示數據存放在緩存中,DataSet裏面能夠包含多個DataTable,DataTable中有多個DataColumn和多個 DataRow,包括對各類對DataTable的操做,以及對列和行的操做,在進行DataSet,DataTable進行操做的時候,應該先判斷它們 是否爲Null,這是最基本的!
1.DataTable,DataRow,DataColumn
①建立本身的DataTable
②使用對象集合初始化器簡化代碼,以及使用「DataColumnCollection」和「DataRowCollection」來操做已添加的行和列
構造函數的訪問修飾符爲Internal,經過這兩個集合能夠對Column和Row進行「增,刪,改,查」,詳細見MSDN,如Remove,Add,RemoveAt etc!
1 dt.Columns.Add(new DataColumn("Age", typeof(Int32))); 2 dt.Columns.Add(new DataColumn() 3 { 4 ColumnName = "Address", 5 DataType = typeof(string), 6 DefaultValue = "江蘇海安" 7 }); 8 //咱們這邊使用Add的方法的第二個重載 9 dt.Rows.Add(new object[] {"11", 44, "222", "yang cao gui"}); 10 //咱們也能夠對添加好的行和列進行讀取和修改 11 dt.Columns[0].ColumnName = "wang wei"; 12 dt.Rows[0]["wang wei"] = "我把這行這列的值修改了,哈哈";
③使用表達樹快速構建本身的列,詳細的也能夠查MSDN
2.DataRowState(行狀態),DataRowVersion(行版本)
①DataRowState(行狀態)是「DataRow」中一個很重要的狀態,主要有五個方面:
1 Added → 添加 2 Deleted → 刪除 3 Detached → 分離 4 Modified → 修改 5 Unchanged → 爲改變
Note:若是實例化一個行,但沒有加入到任何一個表中,那麼它的狀態永遠是Detached,不存在Add,Modified之分,這個是要注意的!
②DataRowVersion(行版本),有四個版本狀態,以下:
1 Current → 最近的行,主要針對Deleted操做以前的行,行狀態的Deleted 2 Default → 行的默認狀態 3 Original → 行的原始值 Added,Modified,Unchanged 4 Proposed → 行的建議值
PS:若是想理解它們,應該要寫一些示例代碼來模擬它們,這樣就能很好的熟悉它們了!
強烈推薦這篇文章:→ 深刻.NET DataTable(寫的很仔細,不錯,必定要看的),還有這篇 → 深刻.NET DataTable(補遺)。
3.DataSet,DataTable
比較重要的方法:Select,Merge,Copy,Clone,GetChanges等等
關於GetChanges方法:獲取數據改變的地方,它所獲取的是你上次調用AcceptChanges方法以後修改數據的信息,這點要注意了!
4.下面是對DataSet和DataTable講的比較好的文章收集
比較兩個DataTable數據(結構相同)——5萬條數據僅需幾秒
5.關於「DataRelation」和「DataView」的知識也很重要
DataView → 表示用於排序、篩選、搜索、編輯和導航的 DataTable的可綁定數據的自定義視圖,看文章:DataSet,DataTable,DataView
DataRelation → 表示兩個 DataTable 對象之間的父/子關係,看文章:DataRelation(DataSet中父子表)的一個示例
九丶封裝數據庫操做類(這纔是精華)
只有充分理解了上面的知識,才能更好的封裝,才能寫出健壯的面向對象數據庫操做類庫,因本人知識有限,簡單的封裝還能夠,可是不足以見人,因此收集了了一些好文章,供咱們來學習:
1.SqlHelper- -高懸的雙刃劍(到底好用麼~~) (提煉更加健壯的代碼)
2.個人DbHelper數據操做類(自定義操做類庫)
3.JSM SqlHelper 2.0 源碼下載(封裝的更細啦,有機會研究研究)
4.微軟原版SQLHelper類(代碼太多,有不少咱們會用不到,還有重載的也太多了吧!)
好了就這麼多了,想簡單也很簡單,想複雜登天還難,哈哈,仍是看我的的選擇把,園子裏面這方面的文章也有不少,一搜一大堆,好好研究下就ok了!
結束:寫了一個星期,終於搞完了,確定還有不少地方沒有涉及到的,你們多多指點...