上一章講到關於C#語法的基礎部分。瞭解相關的基礎部分之後我們就要去瞭解一下C#是什麼樣子訪問數庫的。C#把訪問資料庫這一部分的知識點叫作ADO.NET。即是JAVA常常講到的JDBC這一部分的知識點了。筆者根據使用資料庫方式的不同又分為有線連接和無線連接(關於有線和無線的叫法是筆者個人定義的。因為看 ...
本章簡言 |
上一章講到關於C#語法的基礎部分。瞭解相關的基礎部分之後我們就要去瞭解一下C#是什麼樣子訪問數庫的。C#把訪問資料庫這一部分的知識點叫作ADO.NET。即是JAVA常常講到的JDBC這一部分的知識點了。筆者根據使用資料庫方式的不同又分為有線連接和無線連接(關於有線和無線的叫法是筆者個人定義的。因為看了不同的書裡面很多叫法)。不管是什麼樣子的叫法。只要明白有線是保持連接的狀態下操作資料庫。而無線是連接之後複製一份副本,關閉連接,對副本進行操作之後,在連接更新資料庫。筆者認為如果只是使用的話,只要瞭解對應的幾個相關的類就可以了。如果有搞研究的話,就是對他內部的一些機制進行學習了。那麼這裡只是講到如何使用。
ADO.NET的概念 |
由於本系列並不是主講ADO.NET。所以這裡筆者只會教上面定義有線連接方式相關的類。不管如何讓我們先看一下ADO.NET類相關聯的所有基類吧。這樣子也方便我們下麵的學習。
下麵是ADO.NET的基類信息
DbConnection類:用於連接數庫的類。相當於JDBC裡面通過DriverManager.getConnection方法獲得Connection介面對應的實例類。
DbCommand類:用於存放數據源執行的 SQL 語句或存儲過程的類。相當JDBC裡面的Statement介面。
DbDataReader類:從數據源讀取行的一個只進流。即是執行SQL結果的存放地方。相當於JDBC裡面的ResultSet介面
DbParameter類:用於表示DbCommand裡面對應的參數。相當於JDBC裡面的PreparedStatement的填充參數一樣子。
DbParameterCollection類:不用看就知道DbParameter類的集合類。
DbTransaction類:用於事務的類。相當於JDBC裡面的conn.setAutoCommit(false)的功能。這個不會不清楚吧。
DbDataAdapter類:這個類常用於DataSet一起用。也就是說他是筆者上面定義的無線連接方式。
DbCommandBuilder類:用於協調 DataSet 的更改與關聯資料庫的單表命令。即是跟上面的DbDataAdapter類常常一起用。
DbConnectionStringBuilder類:用於生成連接字元串。
事實上ADO.NET所有的類都是基於上面的基類。想要使用ADO.NET的話,只要瞭解上面的基類就可以了。如果更深入的話,筆者也不清楚什麼做了。至於上面的基類C#把他們按類層次劃分為連接類和非連接類。如下麵筆者在網路上找到的一張圖片。我們就可以很清楚的知道哪一些是連接類,哪一些是非連類。
顯然連接就是連接數庫時用的類,非連接就是在沒有資料庫的情況相關類了。而上面筆者是根據操作資料庫模式進行劃分的。希望不要誤導各位的理解。上面左邊的方框裡面就是屬於連接類,右邊的方框是屬於非連接類。
連接類:DbConnection類、DbCommand類、DbTransaction類、DbParameter類、DbDataAdapter類
非連接類:DataTable類、DataRow類、DataRowCollection類、DataColumn類、DataColumnCollection類、DataRelation類、DataRelationCollection類
學習ADO.NET,事實上就是學習ADO.NET對應的類。有了我們對上面類的一定的瞭解之後。筆者只要自己動手寫一個小例子就可以理解和明白了。
ADO.NET的例子 |
筆者的資料庫用是SQL Server 2008。新建一個資料庫,筆者將他命名為Ado。在新建一個張表為Catalogs。如下SQL語句
表的SQL:
CREATE TABLE [dbo].[Catalogs]( [ID] [int] NOT NULL, [CatalogName] [nvarchar](50) NULL, [CatalogCode] [nvarchar](50) NULL, CONSTRAINT [PK_Catalogs] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
數據的SQL:
INSERT [Catalogs] ([ID], [CatalogName], [CatalogCode]) VALUES (1, N'圖書', N'c0001') INSERT [Catalogs] ([ID], [CatalogName], [CatalogCode]) VALUES (2, N'電腦', N'c0002')
好了。有了上面的數據和表之後,筆者就要簡單做一個獲得數據的例子來學習ADO.NET的知識。
一、首先我們要想辦法和資料庫發生關係。即是連接到資料庫。對JDBC來講第一步是載入對應資料庫驅動。相信下麵這段代碼做JAVA不可能不懂吧。可惜C#這邊卻好像沒有這一步。JDBC做了這一步之後才開始獲得對應的連接類實例。
JDBC的載入驅動:
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
JDBC的獲得連接:
String url = "jdbc:sqlserver://localhost;databaseName=AAA";
Connection conn = DriverManager.getConnection(url,"sa","123");
至於ADO.NET卻沒有那麼複雜。直接實例化一個資料庫連接類就行了。如下的代碼
ADO.NET的獲得連接:
SqlConnection connection = new SqlConnection("Data Source=.;Initial Catalog=Ado;User ID=sa;Password=123");
這裡筆者講一個小手段。相信JDBC在獲得連接字元串的時候,是一件很頭痛的事情。只能百度或死記。而C#這邊如果用的是SQL Server 的話。到是可以用VS的“伺服器資源管理器”視圖來獲得對應的連接字元串。
右擊圖上的“數據連接”》添加連接(A)
這個時候就是彈出一個讓你選擇要連接的資料庫信息。如圖下。
先在伺服器名的方框中填寫"."。然後在選擇使用WINDOW 或是 SQL SERVER。最後你就可以在“選擇或輸入資料庫名稱”中下拉選擇你所對應的資料庫了。這個時候點擊確定按扭就會在“伺服器資源管理器”視圖中“數據連接”下方多出一個連接。先擇右擊》屬性
點擊“屬性(R)”之後就會彈出對應的屬性窗體了。這才是我們最後需要的信息了。如圖下。看到連接字元串了沒有。就是他了。複製一下就可以了。只是密碼部分修改一下就可以了。因為他是******。這是不對的。
連接字元串對應的值:
Data Source=.;Initial Catalog=Ado;User ID=sa;Password=***********
SqlConnection類就是DbConnection類的子類。有心的讀者可能看出一些問題來。是不是說明一點:每一個不同的資料庫是不是對應的在Connection前面加上對應的關鍵字母呢?即是XxxConnection。Xxx可能會變。沒有錯。筆者想說一點就是這個。在JDBC裡面不同的資料庫會載入不同的驅動。如MySql就載入MySql的驅動。Sql Sever就是載入Sql Sever的驅動。只是C#這邊沒有對應的載入驅動的說法。事實上筆者認為有。只是變了而以。XxxConnection的Xxx便是最好的體現。
二、新建一個SQL命令。即是新建一個DbCommand類對應的實例類。這個部分相當JDBC的Statement stmt = conn.createStatement()了。
C#:
SqlCommand command = new SqlCommand(); command.Connection = connection; command.CommandText = "SELECT TOP 1000 [ID] ,[CatalogName] ,[CatalogCode] FROM [Ado].[dbo].[Catalogs]"; command.CommandType = System.Data.CommandType.Text;
SqlCommand類是DbCommand類的子類。這個筆者說了是白說。上面我們知道了DbCommand類的功能。SqlCommand類理解為用於存放SQL命令。同時用於觸發SQL命令的執行。首先讓我們看一下上面的代碼。其中Connection屬性和CommandText屬性相信大家都明白。如果只是存放SQL命令卻不給他對應的連接,他又什麼知道去哪裡查資料庫呢?所以有Connection屬性就知道去找哪個資料庫了,有CommandText屬性就是知道要對這個資料庫做什麼。而CommandType屬性是表示要做的SQL命令是什麼類型的。只是SQL語句,還是存儲過程,或是只直獲得表。(這裡的變數connection是上面代的connection一樣子)
C#:
1 // 摘要: 2 // 指定如何解釋命令字元串。 3 public enum CommandType 4 { 5 // 摘要: 6 // SQL 文本命令。(預設。) 7 Text = 1, 8 // 9 // 摘要: 10 // 存儲過程的名稱。 11 StoredProcedure = 4, 12 // 13 // 摘要: 14 // 表的名稱。 15 TableDirect = 512, 16 }
現在SqlCommand類對象實例知道了連接的資料庫,也知道要執行SQL命令。接下來便是生成對應的結果。即是執行。那麼在執行的時候,又會分了查詢和增刪改。這一點JDBC也有。Statement介面的executeQuery方法和executeUpdate方法就是最好的證明瞭。不用筆者多說了。同樣子,C#也一樣,只是方法名不一樣子而以。ExecuteReader方法就是相當於executeQuery方法。但記得ExecuteReader方法這邊一般是不用參數的。ExecuteNonQuery方法相當於executeUpdate方法。理解了這倆個方法就好辦了。在執行這倆個方法之前,我們還有做一件事情就是打開連接。代碼如下
C#:
connection.Open();//打開連接 SqlDataReader dr = command.ExecuteReader();//執行SQL命令
三、處理SQL命令的結果。即是利用SqlDataReader類來獲得對應的結果。JDBC中在獲得結果的時候,就是利用ResultSet介面。顯然倆者很類似。
C#:
SqlDataReader dr = command.ExecuteReader();//執行SQL命令 while (dr.Read()) { Console.WriteLine(string.Format("CatalogName:{0} CatalogCode:{1}", dr[0], dr["CatalogCode"])); } dr.Close(); connection.Close();
跟JDBC真的很類似,其中dr.Read()就跟ResultSet介面的next()方法類似。而dr[0]和dr["CatalogCode"]跟ResultSet介面的getString()方法類似。註意在執行結束之後要關閉SqlDataReader類和SqlConnection類。讓我們看一下執行的結果吧。
上面筆者只做查詢的例子卻沒有做增刪改的例子。因為筆者相信對你們來是小事了。只要把SQL命令修改成增刪改的語句和ExecuteReader方法變成為ExecuteNonQuery方法。當然這時候就沒有返回SqlDataReader類的對象了。有的只是影響的行數而以。代碼如下
C#:
SqlConnection connection = new SqlConnection("Data Source=.;Initial Catalog=Ado;User ID=sa;Password=123"); SqlCommand command = new SqlCommand(); command.Connection = connection; command.CommandText = "UPDATE Catalogs SET CatalogName='小吃' WHERE ID =1"; command.CommandType = System.Data.CommandType.Text; connection.Open();//打開連接 int affectCount = command.ExecuteNonQuery(); if (affectCount > 0) { Console.WriteLine("修改成功"); } else { Console.WriteLine("修改失敗"); } connection.Close();
上面是簡單的修改。只要讀者們自己組裝SQL語句就可以了。那麼有沒有跟JDBC的PreparedStatement介面功能一樣子的方式嗎。答案是有的。筆者就直接把代碼貼出。你們看一下就知道什麼用了。
C#:
SqlConnection connection = new SqlConnection("Data Source=.;Initial Catalog=Ado;User ID=sa;Password=123"); SqlCommand command = new SqlCommand(); command.Connection = connection; command.CommandText = "UPDATE Catalogs SET CatalogName=@CatalogName WHERE ID =@ID"; command.CommandType = System.Data.CommandType.Text; connection.Open();//打開連接 command.Parameters.Add(new SqlParameter("@CatalogName", "小吃")); command.Parameters.Add(new SqlParameter("@ID" ,1)); int affectCount = command.ExecuteNonQuery(); if (affectCount > 0) { Console.WriteLine("修改成功"); } else { Console.WriteLine("修改失敗"); } connection.Close();
以上的內容主要是講了關於有線連接的方式。筆者上面就說過有倆種。一種是有線,一種是無線。關於無線更多是用到SqlDataAdapter類和DataSet類。希望讀者們自行研究。
本章總結 |
本章主要是講到ADO.NET的部分知識點。專對有線連接的部分知識。對於後面開發.NET來講會有一定會幫助。不過相信現在有很人不知道ADO.NET是什麼。更多都被ORM框架取代了。