這次我們詳細研究DataReader。我個人最喜歡的就是DataReader,雖然它不如DataSet強大,但是在很多情況下我們須要的是靈活的讀取數據而不是大量的在內存裏面緩存數據。比如在網絡上每個用戶都緩存大量的dataset,這很可能導致服務器內存不足。另外dataReader尤其適合讀取大量的數據,因爲它不在內存中緩存數據。
由於下面的討論都設計到數據庫操作,我們虛擬一個小項目:個人通訊錄(單用戶),這意味着我們須要一個contract的數據庫,包含admin和fridend:
admin :Aname,Apassword
friend :Fname,Fphone,Faddress,Fid(主鍵)
當然,你可以根據自己的須要設計friend表,比如添加Fsex等字段,這裏不詳細列舉。對應數據庫建立文件:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[admin]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
drop table [dbo].[admin]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[friend]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[friend]
GO
CREATE TABLE [dbo].[admin] (
[Aname] [varchar] (8) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[Apassword] [varchar] (16) COLLATE Chinese_PRC_CI_AS NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[friend] (
[Fid] [int] IDENTITY (1, 1) NOT NULL ,
[Fname] [varchar] (8) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[Fphone] [varchar] (12) COLLATE Chinese_PRC_CI_AS NULL ,
[Faddress] [varchar] (100) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
在討論DataReader之前我們必須瞭解Connection和Command,雖然前面我們已經簡短的介紹過了。
以下的所有討論都針對Sql Server2000,使用的命名空間爲System.Data.SqlClient。當然如果你須要使用OleDb,那是很方便的(基本上是把Sql替換成爲OleDb就可以了)。
1, SqlConnection類
連接Sql server首先必須實例化一個SqlConnection對象:
<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />SqlConnection Conn = new SqlConnection(ConnectionString);
Conn.Open();
或者
SqlConnection Conn = new SqlConnection();
Conn.ConnectionString = ConnectionString;
Conn.Open();
我比較喜歡前者,但是當你須要重新使用Connection對象去連接另外的數據庫的時候,第二種方法非常有效(不過這種機會很少,一般來說一個小型系統只對應一個數據庫——個人認爲^_^)。
SqlConnection Conn = new SqlConnection();
Conn.ConnectionString = ConnectionString1;
Conn.Open();
//do something
Conn,Close();
Conn.ConnectionString = ConnectionString2;
Conn.Open();
//do something else
Conn,Close();
注意只有關閉一個連接以後才能使用另外的連接。
如果你不清楚Connection對象的狀態,可以使用State屬性,它的值爲Open或者Closed,當然也還有其他值如Executing或者Broken,但是Sql server等當前版本都不支持。
If(Conn.State == ConnectionState.Open)
Conn.Colse();
上面一直提到ConnectionString,一般連接sql server的字符串爲:
Data source = serverName;Initial catalog =contract;user id =sa;password= yourpassword;
如果你的sql server使用的是windows集成密碼,則是:
Data source = serverName;Initial catalog = contract;Integrated Security=SSPI;
至於其他的oledb或者odbc連接串可以到http://www.connectionstrings.com
連接上數據庫以後一定記得關閉連接,在ado.net中當Connection對象超出範圍時連接不會自動關閉。
打開數據庫連接以後我們要執行命令,所以我們討論一下Command類
2 SqlCommand類
建立數據庫連接以後我們須要訪問和操作數據庫——CRUD:Create、Read、Update、Delete。
爲了執行命令我們創建Command對象,Comand對象要求執行Connection對象和CommandText對象。
SqlCommand cmd = new SqlCommand();
cmd.Connection = ConnectionObject;//比如我們先前建立的Conn對象
cmd.CommandText = CommandText;//比如一個Select語句
string CommandText = “Select * from friend”;
當然我們也可以使用存儲過程,這個以後討論。
另外的方法:
SqlCommand cmd = new SqlCommand(CommandText);
cmd.Connection = ConnectionObject;//比如我們先前建立的Conn對象
或者
SqlCommand cmd = new SqlCommand(CommandText,ConnecionObject);
另外還有一個包含三個參數的構造函數,我們不討論。設計到的是事務處理。
有了Command對象以後我們須要執行操作,但是執行前請一定記得打開你的數據庫連接,否則會有異常。SqlCommand對象提供下面4個執行方法:
l ExecuteNonQuery
l ExecuteScalar
l ExecuteReader
l ExecuteXmlReader
ExecuteNonQuery方法執行不返回結果的命令,通常使用它執行插入、刪除、更新操作。
例如我們對contract數據庫進行操作:
string sqlIns = “insert [friend] (Fname,Fphone,Faddress) values (‘雪冬寒’,’027-87345555’,’武漢大學宏博公寓’);
cmd.CommandText = sqlIns;
cmd.ExecuteNonQuery();
string sqlUpdate = “update [frined] set Faddress = ‘武漢大學’ where Fid = 1”;
cmd.CommandText = sqlUpdate;
cmd.ExecuteNonQuery();
string sqlDel = “delete from [friend] where Fid = 1;
cmd.CommandText = sqlDel;
cmd.ExecuteNonQuery();
注:如果你要測試以上代碼,請自己書寫,不要複製和粘貼,這樣會存在文字錯誤(漢語和英語的符號問題)。
ExecuteScalar方法執行返回單個值的命令,例如我們須要統計系統中所有聯繫人的數量,就可以這樣:
SqlCommand cmd = new SqlCommand(“select count(*) from friend”, Conn);
Conn.open();
int friendCount = (int) cmd.ExecuteScalar();
MessageBox.Show(“共” + friendCount.ToString() + “個聯繫人”);
說明:命令可以返回多個結果,此時ExecuteScalar方法將返回第一行第一個字段的值,同時其他所有值不可訪問,這意味着如果象獲得最好的性能,您應該構造適當的select查詢,以便查詢的結果集中儘可能少的包含額外的數據。如果只對單個返回值感興趣,這個方法是首選的方法。另外該方法返回object類型數據,所有保證進行適當的類型轉換是您的責任,否則您將得到異常。
ExecuteXmlReader方法執行返回一個xml字符串的命令。它將返回一個包含所返回的sml的System.Xml.XmlReader對象。這個方法我一無所知,不作討論^_^。
(由於文章不能操作64k,我只能分開貼)