第7章使用C#和ADONET操作數(shù)據(jù)庫(kù)_第1頁(yè)
第7章使用C#和ADONET操作數(shù)據(jù)庫(kù)_第2頁(yè)
第7章使用C#和ADONET操作數(shù)據(jù)庫(kù)_第3頁(yè)
第7章使用C#和ADONET操作數(shù)據(jù)庫(kù)_第4頁(yè)
第7章使用C#和ADONET操作數(shù)據(jù)庫(kù)_第5頁(yè)
已閱讀5頁(yè),還剩37頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論