




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二第7章使用使用C#C#和和ADO.NETADO.NET操作數(shù)據(jù)庫(kù)操作數(shù)據(jù)庫(kù) 本章要點(diǎn)v數(shù)據(jù)提供程序的選擇vSqlConnection的使用vOleDbConnection的使用vOracleConnection的使用v數(shù)據(jù)的獲取vDataReader的使用vDataSet和DataAdapter的使用數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.1 數(shù)據(jù)庫(kù)的連接7.1.1 SqlConnection的使用 ConnectionString 類似于 OLE DB 連接字符串,但并不相同。可以使用 ConnectionString 屬性連接到數(shù)據(jù)庫(kù)。 Pers
2、ist Security Info=False; Integrated Security= SSPI; database =northwind; server = mySQLServer“ 下面的例子創(chuàng)建一個(gè) SqlConnection并設(shè)置它的一些屬性。 public void CreateSqlConnection() SqlConnection myConnection = new SqlConnection(); myConnection.ConnectionString=Persist Security Info=False;” + “Integrated Security=SSPI
3、;database=northwind;” + “server=mySQLServer;Connect Timeout=30; myConnection.Open(); 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.1.2 OleDbConnection的使用 下面的例子創(chuàng)建一個(gè) OleDbCommand 和 一個(gè) OleDbConnection。OleDbConnection 打開,并設(shè)置為 OleDbCommand 的 Connection。然后,該例子調(diào)用 ExecuteNonQuery 并關(guān)閉該連接。為了完成此任務(wù),將為 ExecuteNonQuery 傳遞一個(gè)連接字符串和一個(gè)查詢字符串
4、, 后者是一個(gè) SQL INSERT 語(yǔ)句。 public void InsertRow(string myConnectionString) / If the connection string is null, use a default. if(myConnectionString = = ) myConnectionString =Provider=SQLOLEDB;Data Source=localhost; Initial Catalog=Northwind;+Integrated Security=SSPI; 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 OleDbConnectio
5、n myConnection =new OleDbConnection(myConnectionString); string myInsertQuery = INSERT INTO Customers (CustomerID, CompanyName) Values(NWIND, Northwind Traders); OleDbCommand myCommand = new OleDbCommand(myInsertQuery); myCommand.Connection = myConnection; myConnection.Open(); myCommand.ExecuteNonQu
6、ery(); myCommand.Connection.Close();7.1.3 OdbcConnection的使用 下面的例子創(chuàng)建一個(gè) OdbcCommand和一個(gè) OdbcConnection。將 OdbcConnection 打開并將其設(shè)置為 dbcCommand.Connection 屬性。然后,該例子調(diào)用 ExecuteNonQuery 并關(guān)閉該連接。為完成此任務(wù),將為 ExecuteNonQuery 傳遞一個(gè)連接字符串和一個(gè)查詢字符串,后者是一個(gè) SQL INSERT 語(yǔ)句。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二public void InsertRow(string myCo
7、nnection) / If the connection string is null, use a default. if(myConnection = ) myConnection=DRIVER=SQL Server;SERVER=MyServer; Trusted_connection=yes;DATABASE=northwind; OdbcConnection myConn = new OdbcConnection(myConnection); string myInsertQuery = INSERT INTO Customers (CustomerID, CompanyName)
8、” + “Values(NWIND, Northwind Traders); OdbcCommand myOdbcCommand = new OdbcCommand(myInsertQuery); myOdbcCommand.Connection = myConn; myConn.Open(); myOdbcCommand.ExecuteNonQuery(); myOdbcCommand.Connection.Close();數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.1.4 OracleConnection的使用 Microsoft .NET Framework Data Provider
9、for Oracle(以下簡(jiǎn)稱為.NET for Oracle)是一個(gè).NET Framework的組件。這個(gè)組件為我們使用.NET訪問Oracle數(shù)據(jù)庫(kù)提供了極大的方便。那些使用.NET和Oracle的開發(fā)人員,再也不必使用那個(gè)并不十分“專業(yè)”的OLEDB來訪問Oracle數(shù)據(jù)庫(kù)了。這個(gè)組件的設(shè)計(jì)非常類似.NET中內(nèi)置的Microsoft .NET Framework Data Provider for SQL Server和OLEDB。如果熟悉這兩個(gè)內(nèi)置的組件,那么再學(xué)習(xí)這個(gè)組件也會(huì)是輕車熟路的。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.2 數(shù)據(jù)的獲取7.2.1 創(chuàng)建Command對(duì)象
10、Command對(duì)象是對(duì)數(shù)據(jù)存儲(chǔ)執(zhí)行命令的對(duì)象。看到這里 讀者可能會(huì)產(chǎn)生疑問,Connection對(duì)象不也能這樣做嗎?是的,但是Connection對(duì)象在處理命令的功能上受到一定的限制,而Command對(duì)象是特別為處理命令的各方面問題而創(chuàng)建的。實(shí)際上,當(dāng)從Connection對(duì)象中運(yùn)行一條命令時(shí),已經(jīng)隱含地創(chuàng)建一個(gè)Command對(duì)象。 有時(shí)其他對(duì)象允許向命令傳入?yún)?shù),但在Connection對(duì)象中不能指定參數(shù)的任何細(xì)節(jié)。使用Command對(duì)象允許指定參數(shù)(以及輸出參數(shù)和命令執(zhí)行后的返回值)的精確細(xì)節(jié)(比如,數(shù)據(jù)類型和長(zhǎng)度)。 因此,除了執(zhí)行命令和得到一系列返回記錄,也可能得到一些由命令提供的附加
11、信息。 對(duì)于那些不返回任何記錄的命令,如插入新數(shù)據(jù)或更新數(shù)據(jù)的SQL查詢,Command對(duì)象也是有用的。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.2.2 執(zhí)行命令 建立了數(shù)據(jù)源的連接和設(shè)置了命令之后,Command對(duì)象執(zhí)行SQL命令有三種方法: ExecuteNonQuery、ExecuteReader和ExecuteScalar。 ExecuteNonQuery 執(zhí)行命令,但不返回任何結(jié)果。 ExecuteReader執(zhí)行命令,返回一個(gè)類型化dataReader。 ExecuteScalar執(zhí)行命令,返回一個(gè)值。 SqlCommand 類也提供了下面兩個(gè)方法: ExecuteResults
12、et為將來使用而保留。 ExecuteXmlReader執(zhí)行命令,返回一個(gè)XmlReader。 (1)用ExecuteNonQuery執(zhí)行命令不會(huì)返回結(jié)果集,只會(huì)返回語(yǔ)句影響的記錄行數(shù),它適合執(zhí)行插入、更新、刪除之類不返回結(jié)果集的命令。如果是SELECT語(yǔ)句,那么返回的結(jié)果是-1,如果發(fā)生回滾這個(gè)結(jié)果也是1。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二下面的程序?qū)rders表執(zhí)行了更新并做了查詢。 using System; using System.Data; using System.Data.SqlClient; public class myDataAccess public stati
13、c void Main() SqlConnection conn = new SqlConnection(Server=localhost; Database=Northwind;User ID=sa;PWD=sa); SqlCommand cmd = new SqlCommand(update Orders set OrderDate=2004-9-1 where OrderID=10248,conn); try conn.Open(); int I = cmd.ExecuteNonQuery(); Console.WriteLine(i.ToString() + rows affected
14、 by UPDATE); cmd.CommandText = select * from Orders; i = cmd.ExecuteNonQuery(); Console.WriteLine(i.ToString() + rows affected by SELECT); 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 catch(Exception ex) Console.WriteLine(ex.Message); finally conn.Close(); (2)使用ExecuteReader方法執(zhí)行的命令,可以返回一個(gè)類型化的DataReader實(shí)例或者IDataReader接口的結(jié)果集
15、。通過DataReader對(duì)象就能夠獲得數(shù)據(jù)的行集合,本節(jié)不準(zhǔn)備詳細(xì)討論DataReader,關(guān)于DataReader的使用將在后面說明。下面是一個(gè)例子: using System; using System.Data; using System.Data.SqlClient;數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 public class myDataAccess public static void Main() SqlConnection conn = new SqlConnection(Server=localhost; Database=Northwind;Uer ID=sa;PW
16、D=sa); SqlCommand cmd = new SqlCommand(select top 20 * from Orders, conn); SqlDataReader reader; /或者IDataReader reader; try conn.Open(); reader = cmd.ExecuteReader(); while(reader.Read() Console.WriteLine(reader0.ToString(); reader.Close(); catch(Exception ex) Console.WriteLine(ex.Message); finally
17、conn.Close(); 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二圖7-3 執(zhí)行結(jié)果編譯執(zhí)行結(jié)果如圖7-3: 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 (3)ExecuteReader方法,如果想獲得數(shù)據(jù)的記錄行數(shù),可以通過select count(*)這樣的語(yǔ)句取得一個(gè)聚合的行集合。對(duì)于這樣求單個(gè)值的語(yǔ)句,Command對(duì)象還有更有效率的方法ExecuteScalar。它能夠返回對(duì)應(yīng)于第一行第一列的對(duì)象(System.Object),通常使用它來求聚合查詢結(jié)果。需要注意的是,如果要把返回結(jié)果轉(zhuǎn)化成精確的類型,數(shù)據(jù)庫(kù)在查詢中就必須強(qiáng)制將返回的結(jié)果轉(zhuǎn)換,否則引發(fā)異常。下面是例子: using
18、System; using System.Data; using System.Data.SqlClient; public class myDataAccess public static void Main() 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 SqlConnection conn = new SqlConnection(Server=localhost; Database=Northwind;Uer ID=sa;PWD=sa); SqlCommand cmd = new SqlCommand(select count(*) from Orders,conn); try conn.
19、Open(); int i = (int)cmd.ExecuteScalar(); Console.WriteLine(record num : + i.ToString(); cmd.CommandText = select cast(avg(Freight) as int) from Orders; int avg = (int)cmd.ExecuteScalar(); Console.WriteLine(avg : + avg.ToString(); cmd.CommandText = select avg(Freight) from Orders; avg = (int)cmd.Exe
20、cuteScalar(); /引發(fā)異常 Console.WriteLine(avg : + avg.ToString(); 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二編譯執(zhí)行結(jié)果如圖7-4下:圖7-4 執(zhí)行結(jié)果 這個(gè)程序中,最后一個(gè)查詢將引發(fā)異常,因?yàn)榫酆戏祷氐慕Y(jié)果是float類型的,無法轉(zhuǎn)換。 (4)ExecuteResultSet(只用于Sql提供者) 這個(gè)方法標(biāo)記為“為將來使用而保留”,如果不小 心調(diào)用了它,就會(huì)拋出一個(gè)異常 System.NotSupportedException. (5)ExecuteXmlReader(只用于Sql提供者) 顧名思義,這個(gè)方法執(zhí)行命令,給調(diào)用者返回一
21、個(gè)XmlReader對(duì)象。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.2.3 參數(shù)化查詢 參數(shù)化的查詢能夠?qū)π阅苡幸欢ǖ膬?yōu)化,因?yàn)閹?shù)的SQL語(yǔ)句只需要被SQL執(zhí)行引擎分析過一次。Command的Parameters能夠?yàn)閰?shù)化查詢?cè)O(shè)置參數(shù)值。Parameters是一個(gè)實(shí)現(xiàn)IDataParamterCollection接口的參數(shù)集合。 不同的數(shù)據(jù)提供程序的Command對(duì)參數(shù)傳遞的使用不太一樣,其中SqlClient和OracleClient只支持SQL語(yǔ)句中命名參數(shù)而不支持問號(hào)占位符,必須使用命名參數(shù),而OleDb和Odbc數(shù)據(jù)提供程序只支持問號(hào)占位符,不支持命名參數(shù)。 對(duì)于查詢語(yǔ)句Sql
22、Client必須使用命名參數(shù),類似于下面的寫法:SELECT * FROM Customers WHERE CustomerID = CustomerID ,Oracle的命名參數(shù)前面不用,使用(:),寫為(:CustomerID)。而對(duì)于OleDb或者Odbc必須使用?占位符,類似于下面的寫法:SELECT * FROM Customers WHERE CustomerID = ?數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二下面以Sql Server為例,說明其使用方法: using System; using System.Data; using System.Data.SqlClient;
23、public class myDataAccess public static void Main(String args) SqlConnection conn = new SqlConnection(Server=localhost;Database=Northwind;UID=sa;PWD=sa); SqlCommand cmd = new SqlCommand(select * from Orders where OrderID=oid,conn); SqlDataReader reader; try int param = Convert.ToInt32(args0); cmd.Pa
24、rameters.Add(oid,param); /使用命名參數(shù) cmd.Parameters0.Direction = ParameterDirection.Input; conn.Open(); reader = cmd.ExecuteReader();數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 while(reader.Read() Console.WriteLine(reader0.ToString(); reader.Close(); catch(Exception ex) Console.WriteLine(ex.Message); finally conn.Close(); 對(duì)于O
25、leDb或者Odbc數(shù)據(jù)提供程序的命令參數(shù),只需要把參數(shù)按照占位符從左到右的順序,匹配給Parameters集合就行了。 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 using System; using System.Data; using System.Data.OleDb; public class myDataAccess public static void Main(String args) OleDbConnection conn = new OleDbConnection(Provider=SQLOLEDB;Server=locahost; Database=Northwind;
26、 User ID=sa;PWD=sa); OleDbCommand cmd = new OleDbCommand(select * from Orders where OrdeID= ? or EmployeeID= ?,conn); OleDbDataReader reader; try int param1 = Convert.ToInt32(args0); int param2 = Convert.ToInt32(args1); cmd.Parameters.Add(aaa,param1); cmd.Parameters.Add(bbb,param2); /參數(shù)對(duì)象還需要名字,但是和查詢
27、語(yǔ)句中的參數(shù)無關(guān) cmd.Parameters0.Direction = ParameterDirection.Input; cmd.Parameters1.Direction = ParameterDirection.Input;數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 conn.Open(); reader = cmd.ExecuteReader(); while(reader.Read() Console.WriteLine(reader0.ToString(); reader.Close(); catch(Exception ex) Console.WriteLine(ex.Messa
28、ge); finally conn.Close(); 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.2.4 執(zhí)行存儲(chǔ)過程 使用Command對(duì)象訪問數(shù)據(jù)庫(kù)的存儲(chǔ)過程,需要指定CommandType屬性,這是一個(gè)CommandType枚舉類型,默認(rèn)情況下CommandType表示CommandText命令為SQL批處理,CommandType.StoredProcedure值指定執(zhí)行的命令是存儲(chǔ)過程。類似于參數(shù)化查詢,存儲(chǔ)過程的參數(shù)也可以使用Parameters集合來設(shè)置,其中Parameter對(duì)象的Direction屬性用于指示參數(shù)是只可輸入、只可輸出、雙向還是存儲(chǔ)過程返回值參數(shù)。 需要注意的是
29、如果使用ExecuteReader返回存儲(chǔ)過程的結(jié)果集,那么除非DataReader關(guān)閉,否則無法使用輸出參數(shù)。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.3 DataReader的使用7.3.1 DataReader簡(jiǎn)介 DataReader(數(shù)據(jù)閱讀器)是從一個(gè)數(shù)據(jù)源中選擇某些數(shù)據(jù)的最簡(jiǎn)單方法,但這也是功能最弱的一個(gè)方法。雖然DataReader不如DataSet強(qiáng)大,但是在很多情況下我們需要的是靈活的讀取數(shù)據(jù)而不是大量的在內(nèi)存里面緩存數(shù)據(jù)。如果在網(wǎng)絡(luò)上每個(gè)用戶都緩存大量的dataset,這很可能導(dǎo)致服務(wù)器內(nèi)存不足。另外dataReader尤其適合讀取大量的數(shù)據(jù),因?yàn)樗辉趦?nèi)存中緩存數(shù)據(jù)。
30、 DataReader對(duì)象提供對(duì)數(shù)據(jù)庫(kù)訪問快速的、未緩沖的、只前向移動(dòng)的只讀游標(biāo),對(duì)數(shù)據(jù)源進(jìn)行逐行訪問數(shù)據(jù);也就是說,它一次讀入一個(gè)行,然后遍歷所有的行。 使用DataReader的時(shí)候,不能直接實(shí)例化DataReader類;而是通過執(zhí)行Command對(duì)象的ExecuteReader方法返回它的實(shí)例。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二例如,OleDbDataReader OleDbReader = OleDbComm.ExecuteReader();使用OleDbCommand對(duì)象的ExecuteReader方法實(shí)例化了一個(gè)DataReader。 using System; using
31、System.Data.OleDb; using System.Data; namespace OlDbRead / / Class1 的摘要說明。 / class Class1 / / 應(yīng)用程序的主入口點(diǎn)。 / 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 STAThread static void Main(string args) string source = Provider=SQLOLEDB; + server=localhost; + uid = sa; pwd=;+ database = northwind; string select = SELECT ContactName,C
32、ompanyName FROM Customers; OleDbConnection conn = new OleDbConnection(source); conn.Open(); OleDbCommand cmd = new OleDbCommand(select, conn); OleDbDataReader aReader = cmd.ExecuteReader(); while(aReader.Read() Console.WriteLine(0 from 1, aReader.GetString(0), aReader.GetString(1); aReader.Close();
33、conn.Close(); 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.3.2 使用DataReader讀取數(shù)據(jù) 前面已經(jīng)介紹了DataReader的基本功能,下面具體闡述一下DataReader的使用方法。 (1)創(chuàng)建DataReader對(duì)象 前面提到過沒有構(gòu)造函數(shù)創(chuàng)建DataReader對(duì)象,通常我們使用Command類的ExecuteRader方法來創(chuàng)建DataReader對(duì)象: SqlCommand cmd = new SqlCommand(commandText,ConnectionObject) SqlDataReader dr = cmd.ExecuteReader(); Dat
34、aReader類最常見的用法就是檢索Sql查詢或者存儲(chǔ)過程返回的記錄。它是連接的只向前和只讀的結(jié)果集,也就是使用它時(shí),數(shù)據(jù)庫(kù)連接必須保持打開狀態(tài),另外只能從前往后遍歷信息,不能中途停下修改數(shù)據(jù)。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 (2)使用命令行為指定DataReader的特征 SqlDataRader dr cmd.ExecuteReader(CommandBehavior.CloseConnection); 上面使用的是CommandBehavior.CloseConnection,作用是 關(guān)閉DataReader的時(shí)候自動(dòng)關(guān)閉對(duì)應(yīng)的ConnectionObject。這樣可以避免忘記
35、關(guān)閉DataReader對(duì)象以后關(guān)閉Connection對(duì)象。這個(gè)參數(shù)能保證開發(fā)者記得關(guān)閉連接。 (3)遍歷DataReader中的記錄 下面是使用 DataReader常用的格式: while(dr.Reader() /do something with the current record 注意如果你對(duì)每一條記錄的操作可能花費(fèi)比較長(zhǎng)的時(shí)間,那么意味著閱讀器將長(zhǎng)時(shí)間打開,那么數(shù)據(jù)庫(kù)連接也將維持長(zhǎng)時(shí)間的打開狀態(tài)。此時(shí)使用非連接的DataSet或許更好一些。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 (4)訪問字段的值 DataReader有兩種方法訪問字段的值。第一種是Item屬性,此屬性返回字
36、段索引或者字段名字對(duì)應(yīng)的字段的值。第二種是Get方法,此方法返回由字段索引指定的字段的值。 Item屬性 每個(gè)DataReader類都定義一個(gè)Item屬性。假如現(xiàn)有一個(gè) DataReader實(shí)例dr,對(duì)應(yīng)的sql語(yǔ)句是select Fid,Fname from friend,則可以使用下面的方法取得返回的值: object ID = dr“Fid”; object Name = dr“Fname”;或者: object ID = dr0; object Name = dr0; 注意索引總是從0開始的。另外本例使用的是object來定義對(duì)ID和Name,因?yàn)镮tem屬性返回的值是object型,
37、但是可以強(qiáng)制類型轉(zhuǎn)換。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 int ID = (int)dr“Fid”; string Name = (string)dr“Fname”; 請(qǐng)記住一定要確保類型轉(zhuǎn)換的有效性,否則將出現(xiàn)異常。 Get方法 每個(gè)DataReader都定義了一組Get方法,比如GetInt32方法把返回的字段值作為.NET clr 32位證書。 下面的例子使用該方式訪問Fid和Fname的值: int ID = dr.GetInt32(0); string Name = dr.GetString(1); 注意雖然這些方法把數(shù)據(jù)從數(shù)據(jù)源類型轉(zhuǎn)化為.NET數(shù)據(jù)類型,但是不執(zhí)行其他的數(shù)
38、據(jù)轉(zhuǎn)換,如不會(huì)把16位整數(shù)轉(zhuǎn)換為32位的。所以必須使用正確的Get方法。另外Get方法不能使用字段名來訪問字段,下面的訪問方法是錯(cuò)誤的: int ID = dr.GetInt32(“Fid”); /錯(cuò)誤 string Name = dr.GetString(“Fname”); /錯(cuò)誤數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.3.3 在DataReader中使用多個(gè)結(jié)果集 DataReader提供了另一個(gè)遍歷結(jié)果集的方法NextResult(),其作用是把數(shù)據(jù)讀取器移動(dòng)到下一個(gè)結(jié)果集,這個(gè)方法可以與Read( )方法協(xié)同工作。 例如,下面的代碼使用DataReader實(shí)現(xiàn)了操作兩個(gè)結(jié)果集: u
39、sing System; using System.Data; using System.Data.SqlClient; namespace ConsoleApplication1 class Class1 / / 應(yīng)用程序的主入口點(diǎn)。 / STAThread static void Main(string args) 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 / TODO: 在此處添加代碼以啟動(dòng)應(yīng)用程序/ string connstr = server = .;Integrated Security=SSPI; database = Northwind; SqlConnection conn
40、 = new SqlConnection(connstr); string SQL = select companyname,contactname from customers;” + “ select firstname,lastname from employees; SqlCommand sqlComm = new SqlCommand(SQL,conn);try conn.Open(); SqlDataReader dr = sqlComm.ExecuteReader(); do Console.WriteLine(0tt1,dr.GetName(0), dr.GetName(1);
41、 while(dr.Read() Console.WriteLine(0tt1,dr.GetSqlString(0), dr.GetSqlString(1); while(dr.NextResult();數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二dr.Close();conn.Close();catch(Exception e) Console.WriteLine(e.Message); finally conn.Close(); Console.ReadLine(); 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二7.4 DataSet和DataAdapter的使用7.4.1 DataSet簡(jiǎn)介 D
42、ataSet 對(duì)象與 ADO Recordset 對(duì)象相似,但功能更為強(qiáng)大,并具有另一重要區(qū)別:DataSet 始終是斷開的。DataSet 對(duì)象表示數(shù)據(jù)的緩存,具有類似數(shù)據(jù)庫(kù)的結(jié)構(gòu),如表、列、關(guān)系和約束。但是,盡管 DataSet 可以并的確像數(shù)據(jù)庫(kù)那樣運(yùn)行,但重要的是:DataSet 對(duì)象不直接與數(shù)據(jù)或其他源數(shù)據(jù)進(jìn)行交互。這使得開發(fā)人員能夠使用始終保持一致的編程模型,而不用理會(huì)源數(shù)據(jù)的駐留位置。所有來自于數(shù)據(jù)庫(kù)、XML 文件、代碼或用戶輸入的數(shù)據(jù)都可添加到 DataSet 對(duì)象中。這樣,由于對(duì) DataSet 進(jìn)行了更改,所以在更新源數(shù)據(jù)之前可以對(duì)這些更改進(jìn)行跟蹤和驗(yàn)證。DataSet 對(duì)
43、象的 GetChanges 方法實(shí)際上是創(chuàng)建了另一個(gè) DatSet,該 DatSet 只包含對(duì)數(shù)據(jù)做出的更改。然后,DataAdapter(或其他對(duì)象)使用此 DataSet 來更新原始的數(shù)據(jù)源。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 創(chuàng)建一個(gè)空DataSet對(duì)象: DataSet ds = new DataSet(); 這樣創(chuàng)建的DataSet對(duì)象的DataSetName屬性被設(shè)置為NewDataSet。該屬性描述DataSet的內(nèi)部名稱,以便以后引用。 此外,也可以在構(gòu)造函數(shù)中指定,它以字符串的形式接受名稱: DataSet ds = new DataSet(MyDataSet); 或者
44、可以這樣簡(jiǎn)單地設(shè)置屬性: DataSet ds = new DataSet(); ds.DataSetName = MyDataSet;7.4.2 DataAdapter簡(jiǎn)介 DataAdapter 是連接到數(shù)據(jù)庫(kù)以填充 DataSet 的對(duì)象。然后,它又連接回?cái)?shù)據(jù)庫(kù),根據(jù) DataSet 保留數(shù)據(jù)時(shí)所執(zhí)行的操作來更新數(shù)據(jù)庫(kù)中的該數(shù)據(jù)。 下面介紹使用DataAdapter填充DataSet的方法。數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 首先定義SQL查詢,創(chuàng)建數(shù)據(jù)庫(kù)連接,然后創(chuàng)建和初始化數(shù)據(jù)適配器: SqlDataAdapter da = new SqlDataAdapter(SQL,sql
45、Conn); 接著創(chuàng)建DataSet對(duì)象: DataSet ds = new DataSet(); 此時(shí),得到的只是空DataSet。關(guān)鍵代碼行是使用數(shù)據(jù)適配器的Fill()方法執(zhí)行查詢,檢索數(shù)據(jù),填充DataSet: da.Fill(ds,Products); Fill()方法從內(nèi)部使用DataReader訪問數(shù)據(jù)庫(kù)數(shù)據(jù)和表達(dá)式,然后使用它填充DataSet。注意這個(gè)方法不只是用于填充DataSet。 下面的代碼顯示了使用SqlDataAdapter的另一種方法,為此,將其SelectCommand屬性設(shè)置為SqlCommand對(duì)象。我們可以使用SelectCommand得到或設(shè)置SQL語(yǔ)句
46、或存儲(chǔ)過程: SqlDataAdapter da = new SqlDataAdapter(); Da.SelectCommand = new SqlCommand(SQL,sqlConn); DataSet ds = new DataSet(); da.Fill(ds,Products);數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 由于填充過的DataSet可供我們支配,所以,可以以DataTable 對(duì)象的形式提取每個(gè)表,并使用該對(duì)象訪問實(shí)際數(shù)據(jù)。 DataSet當(dāng)前只含有一個(gè)表: DataTable dt = ds.TablesProducts; 最后,使用嵌套的foreach循環(huán),從每個(gè)
47、行訪問列數(shù)據(jù),并且把輸出輸出到屏幕: foreach(DataRow dRow in dt.Rows) foreach(DataColumn dCol in dt.Columns) Console.WriteLine(dRowdCol); 7.4.3 利用DataSet和DataAdapter訪問數(shù)據(jù) 數(shù)據(jù)集是一個(gè)容器,因此需要用數(shù)據(jù)填充它。填充數(shù)據(jù)集時(shí),將引發(fā)各種事件,應(yīng)用約束檢查等等。可以用多種方法填充數(shù)據(jù)集:數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 (1)調(diào)用數(shù)據(jù)適配器的 Fill 方法。這導(dǎo)致適配器執(zhí)行 SQL 語(yǔ)句或存儲(chǔ)過程,然后將結(jié)果填充到數(shù)據(jù)集中的表中。如果數(shù)據(jù)集包含多個(gè)表,每個(gè)
48、表可能有單獨(dú)的數(shù)據(jù)適配器,因此必須分別調(diào)用每個(gè)適配器的 Fill 方法。 (2)通過創(chuàng)建 DataRow 對(duì)象并將它們添加到表的 Rows 集合,手動(dòng)填充數(shù)據(jù)集中的表(只能在運(yùn)行時(shí)執(zhí)行此操作,無法在設(shè)計(jì)時(shí)設(shè)置 Rows 集合。)。 (3)將 XML 文檔或流讀入數(shù)據(jù)集。 (4)合并(復(fù)制)另一個(gè)數(shù)據(jù)集的內(nèi)容。如果應(yīng)用程序從不同的來源(例如,不同的 XML Web services)獲取數(shù)據(jù)集,但是需要將它們合并為一個(gè)數(shù)據(jù)集,該方法會(huì)很有用。下面通過一個(gè)例子來說明使用DataSet和DataAdapter訪問數(shù)據(jù)庫(kù)。 數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二using System;using
49、System.Data;using System.Data.SqlClient;using System.Drawing;using System.Windows.Forms;public class DataGridSample:Form DataSet ds; DataGrid myGrid; static void Main() Application.Run(new DataGridSample(); public DataGridSample() InitializeComponent(); void InitializeComponent() this.ClientSize = n
50、ew System.Drawing.Size(550, 450); myGrid = new DataGrid(); myGrid.Location = new Point (10,10); myGrid.Size = new Size(500, 400); myGrid.CaptionText = Microsoft .NET DataGrid; this.Text = C# Grid Example;數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 this.Controls.Add(myGrid); ConnectToData(); myGrid.SetDataBinding(ds, Suppl
51、iers); void ConnectToData() / Create the ConnectionString and create a SqlConnection / Change the data source value to the name of your computer string cString = Persist Security Info=False;Integrated Security=SSPI; database=northwind;server=mySQLServer; SqlConnection myConnection = new SqlConnectio
52、n(cString); / Create a SqlDataAdapter SqlDataAdapter myAdapter = new SqlDataAdapter(); myAdapter.TableMappings.Add(Table, Suppliers); myConnection.Open(); SqlCommand myCommand = new SqlCommand(SELECT * FROM Suppliers, myConnection); myCommand.CommandType = CommandType.Text; myAdapter.SelectCommand =
53、 myCommand; Console.WriteLine(The connection is open); ds = new DataSet(Customers); myAdapter.Fill(ds);數(shù)據(jù)庫(kù)原理及應(yīng)用2022年5月3日星期二 / Create a second Adapter and Command SqlDataAdapter adpProducts = new SqlDataAdapter(); adpProducts.TableMappings.Add(Table, Products); SqlCommand cmdProducts = new SqlCommand(SELECT * FROM Produc
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- BP-Fluor-555-azide-生命科學(xué)試劑-MCE
- 義務(wù)教育道德與法治課程標(biāo)準(zhǔn)(2022年版)
- 定期報(bào)告:六月繼續(xù)震蕩偏強(qiáng)結(jié)構(gòu)性行情依舊
- 2025中國(guó)“雙一流”高校醫(yī)學(xué)建設(shè)數(shù)據(jù)分析報(bào)告
- 2025年零售門店運(yùn)營(yíng)數(shù)字化技術(shù)應(yīng)用:智能化客服與體驗(yàn)提升報(bào)告
- 2025年工業(yè)廢氣深度凈化技術(shù)產(chǎn)業(yè)鏈上下游協(xié)同發(fā)展研究報(bào)告
- 醫(yī)療行業(yè)大數(shù)據(jù)隱私保護(hù)技術(shù)在疾病預(yù)測(cè)中的應(yīng)用報(bào)告
- 教育投資并購(gòu)2025戰(zhàn)略布局報(bào)告:整合策略與行業(yè)洞察
- 2025年生物質(zhì)能源在微電網(wǎng)分布式能源系統(tǒng)中的應(yīng)用前景與優(yōu)化策略報(bào)告
- 工業(yè)互聯(lián)網(wǎng)平臺(tái)2025年網(wǎng)絡(luò)安全態(tài)勢(shì)感知技術(shù)信息安全技術(shù)前沿動(dòng)態(tài)報(bào)告
- 2025至2030中國(guó)控制按鈕開關(guān)行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢(shì)及投資規(guī)劃深度研究報(bào)告
- 臨商銀行股份有限公司招聘筆試真題2024
- 近代史第三章試題及答案
- DB31-T 1593-2025 基于自動(dòng)駕駛功能的公交運(yùn)營(yíng)技術(shù)要求
- 地理●甘肅卷丨2024年甘肅省普通高中學(xué)業(yè)水平等級(jí)性考試高考地理真題試卷及答案
- 醫(yī)院純水系統(tǒng)管理制度
- 2025年中考英語(yǔ)考前沖刺押題模擬試卷 3套(含答案)
- 吊裝-運(yùn)輸方案(3篇)
- 2025年小升初語(yǔ)文復(fù)習(xí):積累運(yùn)用 專項(xiàng)匯編(含答案)
- 靜脈留置針大賽理論考核考試試題及答案
- 【8道期末】安徽省蕪湖市無為市2023-2024學(xué)年八年級(jí)下學(xué)期期末道德與法治試題(含解析)
評(píng)論
0/150
提交評(píng)論