標籤:des http 使用 strong 檔案 資料
什麼是ADO.NET?
ADO.NET就是一組類庫,這組類庫可以讓我們通過程式的方式訪問資料庫,就像System.IO下的類用類操作檔案一樣,System.Data.這組類是用來操作資料庫(不光是MSSql Server),它提供了統一的編程介面讓操作其它資料庫(Access、Oracle等)的方式和操作MSSql Server一致。
Ado.net目的:通過程式訪問資料庫。
Ado.Net組成:
資料提供者(常用類):
Connection,用來串連資料庫;
Command,用來執行SQL語句;
DataReader唯讀、只進的結果集,一條一條讀取資料(StreamReader、XmlReader微軟的類庫中這些Reader的使用方式都差不多);
DataAdapter,一個封裝了上面3個對象的對象;資料集(DataSet),臨時資料庫,斷開式資料操作。
其它常見類:
ConnectionStringBuilder//自動產生連接字串;
Parameter//帶參數的SQL語句;
Transaction//在ADO.NET中使用事務;
與DataSet相關的類:
DataView//視圖類,DataTable中的資料以不同的視角查看
DataRowView//DataView中的行。
DataTable //DataSet中的資料表
DataRow//DataTable中的行
DataColumn//DataTable中的列
DataRealation//DataTable與DataTable的關係
Constraint//DataTable中建立的約束
Ado.Net訪問資料的方式:
(1)
1.串連資料用Connection
2.執行SQL語句Command
3.執行完畢之後將結果一條一條返回。DataReader
(2)
使用DataAdapter+DataSet,這種方法本質還是通過Connection、Command、DataReader將資料全部取出來然後放到了DataSet中。//看DataAdapter的建構函式。
Connection
如何讓應用程式與資料庫建立串連?
Connection對象。Connection就像讀取資料庫資料之前先要建立一條路,在讀取Sql Server資料庫使用。
串連資料的步驟:
- 建立SqlConnection對象
- 擷取連接字串
- VS視圖-伺服器總管-資料庫連接上點右鍵-添加串連在新添的資料庫上點右鍵屬性裡有連接字串
- 使用SqlConnectionStringBuilder協助擷取連接字串
- 使用PropertyGrid控制項的SelectedObject屬性與SqlConnectionStringBuilder配合使用。
- 開啟串連.(只能開啟一次,可以多次關閉。測試是否開啟時可以使用:ConnectionState枚舉)
- 關閉串連//相當於設定了路障
- 釋放資源//相當於把路拆了,這塊地可以蓋樓了。
- 調用Connection.Dispose()【繼承自Component類的方法】方法時,內部調用了Close()
- connection不能重複開啟。
串連池:InnerConnection。用串連池開啟串連:Data Source=.\\sqlexpress;Initial Catalog=MySchool;IntegratedSecurity=True;
ADO.Net中通過SqlConnection類建立到SQLServer的串連,SqlConnection代表一個資料庫連接,ADO.Net中的串連等資源都實現了IDisposable介面,可以使用using進行資源管理。
sqlconnection在程式中一直保持它open可以嗎?
對於資料庫來說,串連是非常寶貴的資源,一定要用完了就close、dispose。【Close以後就可以放到“池”中了,其他連結就可以再次使用了。】
Command
操作Sql Server資料庫使用SqlCommand對象,SqlCommand表示向伺服器提交的一個命令(SQL語句等) , CommandText屬性為要執行的SQL語句.
建立SqlCommand對象:
1.通過new關鍵字建立
2.通過IDbConnection.CreateCommand()方法建立(編寫通用代碼的時候使用(多態))
常用的三個方法:
ExecuteNonQuery() 執行對資料庫的增刪改,返回受影響的行數,適合:insert、delete、update(對於其他語句返回-1)
ExecuteScalar() 執行查詢,返回首行首列
ExecuteReader() 執行查詢,返回DataReader對象
StatementCompleted事件:
每條SQL語句執行完畢之後觸發。多條語句同時執行(用分號隔開),如何擷取每條語句所影響的行數?//實際傳回值為每條語句所影響的行數的和。
ExecuteScalar
SqlCommand的ExecuteScalar方法用於執行查詢,並返回查詢所返回的結果集中第一行的第一列,因為不能確定傳回值的類型,所以傳回值是object類型。
得到自動成長欄位的主索引值,在values關鍵詞前加上output inserted.Id,其中Id為主鍵欄位名。執行結果就試插入的主索引值,用ExecuteScalar執行最方便。(output語句使用的是inserted、deleted兩個暫存資料表)
cmd.CommandText =“insert into class(cName,cDescription) output inserted.classId values(‘高三一班’,‘描述’)”;int i = Convert.ToInt32(cmd.ExecuteScalar());
原來的寫法:
cmd.CommandText =“insert into class(cName,cDescription) values(‘高三一班’,‘描述’);select @@identity”;int i = Convert.ToInt32(cmd.ExecuteScalar());@@IDENTITY 可以返回當前會話中的所有表中產生的最後一個標識值。
執行查詢
執行有多行結果集的用ExecuteReader。
SqlDataReader reader = cmd.ExecuteReader();...
while (reader.Read()){Console.WriteLine(reader.GetString(1));}
reader的強型別的GetString()、GetInt32、GetFloat()、GetDouble()等方法只接受整數參數,也就是序號,用GetOrdinal方法根據列名動態得到序號,更簡單的方法reader[‘uUserName’]。
使用reader根據列索引讀取列資料而不是列名(列名最後也轉化為索引);//一般如果沒有特殊情況建議使用索引來擷取列資訊,不要使用列名(效率較 低)。//根據列名來擷取資料的話,比較好的寫法是:int c1=reader.GetOrdinal("lie1");object obj1=reader[c1]; reader.GetDataTypeName()//當前列的資料類型。
為什麼用using?
Close:關閉以後還能開啟。Dispose:直接銷毀,不能再次使用。using在出了範圍以後調用Dispose,SqlConnection、SqlDataReader等的Dispose內部都會做這樣的判斷:判斷有沒有close,如果沒有Close就先Close再Dispose。
DataReader的HasRow實現://判斷如果close,則直接拋出異常。
public override boolHasRows { get { if (this.IsClosed) { throw ADP.DataReaderClosed("HasRows"); } return this._hasRows; } }
注意:DataReader必須獨享一個Connection 。 (除非設定了允許MARS,多活動結果集,在連接字串中)。
SqlDataReader使用注意事項
返回reader後資料在哪裡?資料庫伺服器緩衝
當使用DataReader的時候必須保證Connection為Open狀態;
reader唯讀(不能通過reader修改資料。)、只進;reader每次讀取一條就釋放一條所以只能向前不能後退;
由於功能有限,所以讀取速度很快,適合從資料庫中讀取大量資料;
HasRow屬性返回是否有行。IsDbNull()判斷資料是否為null;
資料庫中的類型與C#的不太一樣,資料庫中的float,得用c#的GetDouble()來擷取;
如果返回多個結果集則使用NexResult()方法。通過do-while迴圈測試。強型別轉換時,需要使用IsDbNull()判斷獲得的資料是否為空白。
通過執行ExecuteReader()方法擷取輸出參數的時候需要將reader.Close()以後才能擷取。
Ado.Net
串連池
由於每次正常串連資料庫都會至少執行3個操作(1.登入資料庫伺服器2.執行操作3.登出使用者),所以每次通過Connection向資料庫伺服器申請一個串連都比較耗時。【ado.net預設啟用了串連池】。
如何清空串連池?Connection的靜態方法ClearAllPools()、ClearPool()。
什麼情況下需要禁用串連池?
一般都不禁用。尤其是asp.net之類的程式,n多個使用者頻繁訪問,但是大多數使用者訪問時採用的都是同一個連接字串。但如果某個應用程式有多個用戶端,每個用戶端訪問時採用的都是各自的連接字串,這時如果採用串連池,雖然每次開啟串連的速度會變快,但是由於“池”的問題同時會儲存多個開啟的連線物件。
注意:一般一個項目中常用的串連也不過幾個而已。
Ado.net
串連池使用總結:
1.第一次開啟串連會建立一個連線物件。
2.當這個串連關閉時(調用Close()方法時)會將當前那個連線物件放入池中。
3.下一個連線物件,如果連接字串與池中現有連線物件的連接字串完全一致(大小寫敏感),則會使用池中的現有串連,而不會重新建立一個。
4.只有對象調用Close(),的時候才會放入池中,如果一個連線物件一直在使用,則下次再建立一個連線物件發現池中沒有,也會再建立一個新連線物件。在池中的連線物件,如果過一段時間沒有被訪問則自動銷毀。
查詢參數
SQL語句使用@ParameterrName表示“此處用參數代替”,向SqlCommand的Parameters中添加參數。參數在SQLServer內部不是簡單的字串替換,SQLServer直接用添加的值進行資料比較,因此不會有注入漏洞攻擊。(帶參數的sql語句內部是調用了預存程序)。
帶參數的一個問題(小bug):
SqlParameter p1=new SqlParameter("@age",0);//只有0會出現意外的問題。當是0的時候會調用另一個重載:SqlParameter(string parameterName,SqlDbType dbType);在0前加object,即有重載對象可以應用。
DataSet(ado.net
斷開式資料訪問)
DataSet是什嗎?
資料的集合、臨時資料庫、記憶體資料庫。(B/S程式與C/S程式對DataSet的不同處理方式)。
DataSet和SqlDataReader的對比:
SqlDataReader是串連相關的,SqlDataReader中的查詢結果並不是放到程式中的,而是放在資料庫伺服器中,SqlDataReader只是相當於放了一個指標(遊標),只能讀取當前遊標指向的行,一旦串連斷開就不能再讀取。這樣做的好處就是無論查詢結果有多少條,對程式佔用的記憶體都幾乎沒有影響。
SqlDataReader為速度而生,唯讀、只進,功能有限。ADO.Net中提供了資料集的機制,將查詢結果填充到本地記憶體中,這樣串連斷開、伺服器斷開都不影響資料的讀取。
DataSet對於多層應用程式之間傳遞資料。(現在大都用List<T>)
語句:DataSet dataset = new DataSet(); SqlDataAdapter adapter = new SqlDataAdapter(cmd); adapter.Fill(dataset);
SqlDataAdapter是DataSet和資料庫之間溝通的橋樑。資料集DataSet包含若干表DataTable,DataTable包含若干行DataRow。foreach (DataRow row in dataset.Tables[0].Rows) row["Name"]。
可以使用不同的SqlDataAdapter來更新DataTable,如果要是用SqlCommandBuilder自動產生的Command對象的話,必須提供selectCommand,但是可以不用Fill。
- 什麼是DataSet?
資料集合、臨時資料庫、記憶體資料庫。但DataSet是通過DataReader填充的。
2.通過DataAdapter填充DataSet,Fill()也可以分頁(並不高效,會在伺服器端都把資料查詢出來,然後用DataReader跳過前面的資料,只取後面要的資料,真正的分頁應該是在資料庫中就只查詢出當前頁的資料。)
3.斷開式資料訪問,操作完成以後調用Update()方法。
DataSource可以綁定什麼類型的資料?
IList介面,包括一維數組。IListSource介面,例如,DataTable和DataSet類。IBindingList介面,例如,BindingList(T) 類。IBindingListView介面,例如,BindingSource類。
注意點:
1.通過DataAdapter的Fill方法填充DataSet中的表。
2.建立DataAdapter的時候,只需指定連接字串和查詢語句,會自動產生SelectCommand。
3.通過SqlCommandBuilder自動建立InsertCommand、DeleteCommand、UpdateCommand,然後就可以調用adapter的Update()方法將 DataTable中的資料更新到資料庫中。
3.1通過SqlCommandBuilder來建立Command對象的時候,必須保證在建立adapter的時候的select語句中包含對主鍵的查詢
4.也可以自己指定Command,我們對DataTable的操作,只是為Rows集合中沒行的RowState狀態做了標記,並沒有將該行從Rows集合中真的刪 除。
多條件搜尋時Where 1=1
當拼接多個where條件時,有時候不知道and|or前面的條件是否存在。往往會在後面跟一個where 1=1,但這種方法並不高效。如果使用這種方式,在資料庫中會坐全表掃描(對每行資料都進行掃描,比對。),會無法使用索引等最佳化查詢的策略。且建的索引將會失效。
解決方案:List+string.join
Ado.Net
中的預存程序
//通過連線物件建立一個事物
SqlTransaction tran=con.BeginTransaction();
Tran.commit();//提交事務
Tran.rollback();//復原事務