天天看點

ADO.NET中的五個主要對象

Connection 物件 

   Connection 對象主要是開啟程式和資料庫之間的連結。沒有利用連結對象将資料庫打開,是無法從資料庫中取得資料的。這個物件在ADO.NET 的最底層,我們可以自己産生這個對象,或是由其它的對象自動産生。 

Command 物件 

   Command 對象主要可以用來對資料庫發出一些指令,例如可以對資料庫下達查詢、新增、修改、删除資料等指令,以及呼叫存在資料庫中的預存程式等。這個對象是架構在Connection 對象上,也就是Command 對象是透過連結到資料源 

DataAdapter 物件 

   DataSetCommand 對象主要是在資料源以及DataSet 之間執行資料傳輸的工作,它可以透過Command 對象下達指令後,并将取得的資料放入DataSet 對象中。這個對象是架構在Command對象上,并提供了許多配合DataSet 使用的功能。在Beta 2 版中DataSetCommand 物件會更名為DataAdapter。 

DataSet 物件 

   DataSet 這個對象可以視為一個暫存區(Cache),可以把從資料庫中所查詢到的資料保留起來,甚至可以将整個資料庫顯示出來。DataSet 的能力不隻是可以儲存多個Table 而已,還可以透過DataSetCommand 對象取得一些例如主鍵等的資料表結構,并可以記錄資料表間的關聯。DataSet 對象可以說是ADO.NET 中重量級的對象,這個對象架構在DataSetCommand 對象上,本身不具備和資料源溝通的能力;也就是說我們是将DataSetCommand 對象當做DataSet 對象以及資料源間傳輸資料的橋梁。 

DataReader 物件 

   當我們隻需要循序的讀取資料而不需要其它操作時,可以使用DataReader 對象。DataReader對象隻是一次一筆向下循序的讀取資料源中的資料,而且這些資料是隻讀的,并不允許作其它的操作。因為DataReader 在讀取資料的時候限制了每次隻讀取一筆,而且隻能隻讀,是以使用起來不但節省資源而且效率很好。使用DataReader 對象除了效率較好之外,因為不用把資料全部傳回,故可以降低網絡的負載。 

ADO.NET   使用Connection   對象來連接配接資料庫,使用Command   或DataAdapter對象來執行SQL語句,并将執行的結果傳回給DataReader   或   DataAdapter   ,然後再使用取得的DataReader   或DataAdapter   對象操作資料結果   

6.2.1   Connection   對象   

    建立Connection   對象的代碼:   

OLEDB:     OleDbConnection   MyConnection=new   OleDbConnection();   

SQL:           SqlConnection       MyConnection=new   SqlConnection();   

◆他們的ConnectionString屬性:擷取或設定連接配接語句。   MyConnection.ConnectionString="server=(local);database=pubs;uid=sa;pwd=''";   

◆DataBase   屬性:擷取目前打開資料庫   

◆DataSource屬性:擷取打開資料庫的連接配接執行個體   

◆Open   方法:打開連接配接         

◆Close   方法:關閉連接配接   

6.2.2   Command與DataReader   對象   

Command   對象中包含了送出資料庫系統的通路資訊。OleDbCommand   與SqlCommand   對象,它們的基本對象和操作方法是相同的,在此介紹OleDbCommand的用法,SqlCommand的用法類推即可.   

如:   OleDbCommand     myComm   =   new   OleDbCommand(strQuery,myConnection);   

      第一個參數是sql語句或存儲過程名,第二個參數是前面的Connection   對象的執行個體   

Command   對象的隻要的屬性和方法有:   

◆Connection   屬性:設定或擷取   Command對象使用的Connection   對象執行個體   

◆CommandText   屬性:設定或擷取需要執行的sql語句或存儲過程名   

◆CommandType   屬性:設定或擷取執行語句的類型。它有3個屬性值:StoredProceduce(存儲過程)   TableDirect     Text(标準的SQL語句)   預設是Text   

◆Parameters   屬性:取得參數值集合   

◆ExecuteReader   方法:執行CommandText指定的SQL語句或存儲過程名,傳回值類型為DataReader   

◆ExecuteNonQuery   方法:與ExecuteReader   功能相同,隻是傳回值為執行sql語句或存儲過程受影響的記錄行數   

DataReader   的主要屬性和方法有:   

◆FieldCount   屬性:顯示目前資料記錄的字段總和   

◆IsClosed     屬性:   判斷DataReader   對象是否已經關閉   

◆Close   方法:關閉DataReader   對象   

◆GetString方法:以String類型傳回指定列中的值   

◆Getvalue   方法:以自身的類型傳回指定列中的值   

◆Getvalues   方法:傳回目前記錄所有字段的集合   

◆Read   方法:将“光标”指向DataReader對象的下一記錄   

Sql連接配接執行個體:   

<%@   Import   Namespace="System.Data"   %>   

<%@   Import   Namespace="System.Data.SqlClient"   %>   

<script   language="C#"   runat="server">   

void   Page_Load(Object   sender,   EventArgs   e)   {   

SqlConnection   Conn=new   SqlConnection();     

Conn.ConnectionString="server=(local);database=pubs;uid=sa;pwd=''";   

Conn.Open();   

SqlCommand   Comm=new   SqlCommand("select   *   from   Authors   ",Conn);   

SqlDataReader   dr=Comm.ExecuteReader();         

dg.DataSource=dr;   

dg.DataBind();   

Conn.Close();   

}   

</script>   

<asp:DataGrid   id="dg"   runat="server"   />   

Aeccess   資料庫連接配接執行個體   (OleDbCommand   和   OleDbDataReader   使用執行個體)   

<%@   Page   Language="C#"   %>   

<%@   Import   Namespace="System.Data"%>   

<%@   Import   Namespace="System.Data.OleDb"%>   

<script   Language="C#"   Runat="Server">   

OleDbDataReader   dr;   

public   void   Page_Load(Object   src,EventArgs   e)   

{   

    string     

myConnstring="provider=Microsoft.Jet.OLEDB.4.0;   Data     

Source="+Server.MapPath(".")+"..\\DataBase\\db2.mdb;";   

string   strSel="Select   *   from     BookMark";   

OleDbConnection   myConn=   new   OleDbConnection   

(myConnstring);   

OleDbCommand   myComm=new   OleDbCommand(strSel,myConn);     

myComm.Connection.Open();   

dr=myComm.ExecuteReader();     

myConn.Close();   

<html>   

<body>   

<form   Runat="Server">   

</form>   

</body>   

</html>   

++++++++++++++++++++++++++++++++++++++++++++++++   

++++++++++++++++++++++++++++++++++++++++++++++++ 

6.3.3   DataSet   與DataAdapter   

DataReader   對象隻能實作對資料的讀取,不能完成其他的操作 

DO.NET提供一款更強大的資料操作對象――DataSet   可以将DataSet看成一個非連接配接的資料庫,因為DataSet的内部存儲結構與資料庫很類似,擁有資料表(DataTable)資料表關聯(DataRelation)。DataSet中可以存儲多張表等。DataSet擁有類似于資料庫的結構,但它并不等同于資料庫。首先他可以存儲來自資料庫的資料,而且還可以存儲其他格式的資料,比如   XML格式文檔;   

1.查詢資料   

講到DataSet的資料庫應用,先要了解ADO.NET中的另一個對象DataAdapter   .   

它也分為SqlDataAdapter   和OleDbDataAdapter   

建DataAdapte:   

OleDbDataAdapter     MyAdapter=new   OleDbDataAdapter();   

SqlDataAdapter           MyAdapter=new   SqlDataAdapter();   

取得的DataAdapter   對象時必須賦予一個連接配接對象:   

MyAdapter.SelectCommand.Connection   =   MyConn;   或   

MyAdapter.UpdateCommand.Connection   =Myconn;   或   

MyAdapter.DeleteCommand.Connection   =   MyConn;   或   

MyAdapter.InsertCommand.Connection   =Myconn;   

如果需要執行SQL語句,那麼還必須給相應的CommandText   屬性指派。代碼為:   

MyAdapter.*Command.CommandText   =   SQL語句;   

寫這麼多行代碼似乎有些麻煩,如果你隻是查詢資料庫,則可以在建立   DataAdapter執行個體時就完成上述工作。   

OleDbDataAdapter   MyAdapter   =   new   OleDbDataAdapter(strSelect,objConnection);   

<%@   Page   Language="C#"   Runat="Server"%>   

MyConnString="Provider=Microsoft.Jet.OLEDB.4.0;Data     

Source="+Server.MapPath(".")+"\\DataBase\\db3.mdb;";   

string   strSel="select   *   from   Score";   

//建立一個DataSet   執行個體   

DataSet   ds=new   DataSet();   

OleDbConnection   MyConn=   new   OleDbConnection(MyConnString);   

OleDbDataAdapter   MyAdapter   =   new   OleDbDataAdapter(strSel,MyConn);   

MyAdapter.Fill(ds,"Score");   

dg1.DataSource=ds.Tables["Score"].DefaultView;   

dg1.DataBind();   

<asp:DataGrid   id="dg1"   runat="Server"     

    Headerstyle-BackColor="#aaaadd"   

    AlternatingItemstyle-BackColor="#eeeeee"   

/>   

将DataAdapter   于   DataSet   相聯系的是   DataAdapter   對象的   Fill   方法。他有很多中用法:     MyDataAdapter.Fill(DataSet)                 MyDataAdapter.Fill(DataSet,TableName)   

MyDataAdapter.Fill(DataSet,   StartRow   ,   RowsCount,   TableName)   

DataSet   綁定至   DataGrid   控件顯示:   

1.dg1.DataSource=   ds.Tables[“Score”].DefaultView;   

2.dg1.DataSource=ds;   

dg1.DataMember=”Score”;   

提示:   DataSet中的各種集合,通路子項有兩種方法,一種是用子項的名,一種是用數字索引.比如要通路表”Score”,可以用:   DataSet.Tables[0]   通路   (多張表依次類推)   

2.   插入資料:   DataSet   的結構和資料庫相似,所有插入資料實質上就是在DataSet   的資料表裡插入一行(DataRow)   

//建立一行   

DataRow   dr=   ds.Tables[“Score”].NewRow();   

                dr.   [“Name”]   =   “addme”;   

                dr.   [“class”]   =”201”;   

ds.Tables[“Score”].Rows.Add(dr);     //将建立的行加到DataTable   的DataRow集合中   

這樣對DataSet的操作僅僅是在DataSet中執行,并不影響資料庫中的資料,要使用DataAdapter   的   Update   方法(有多種方法).   

    1.   DataAdapter.Update(DataSet)   ;       2.   DataAdapter.Update(DataSet,   TableName);   

3.更新資料:   實際就是在DataSet   資料行上面直接修改資料   

DataRow   dr   =   ds   .Tables[“Score”].Rows[0];     //取出第一行   

dr.   [“Name”]   =   “比爾”;     //修改   

如果要更新資料庫,則再調用   Update   方法         

4.删除資料:   找到相應的資料行,然後删除   

DataRow   dr   =ds.Tables[“Score”].Row[0];     dr.Delete();   

注意:   DataAdapter   對象在資料發生改變時,并不能自動産生資料庫系統所需的交易sql語句,所有要建立一個CommandBuilder   對象   它能自動産生交易的sql語句.   

OleDbCommandBuilder   custcb   =   new   OleDbCommandBuilder(MyAdapter);   

5.DataSet   的其他特征   

DataSet   、DataTable   和DataRow   都有一個十分有用的方法----RejectChanges,   

它時操作對象拒絕已經發生的改變,将資料複原.該方法于AcceptChanges   HasErrors等屬性連用非常有用.   

If   (DataSet.HasErrors)   

    DataSet.RejectChanges();   

else   

    DataSet.AcceptChanges(); 

  在前面一講中,我們應該已經熟悉了如何使用DataAdapter對象來進行資料更新(在前面一篇如何處理出錯裡面寫了一個簡單的例子),下面我們先進行一下總結,然後再講解一下通過Command對象如何更新資料。 

          一、通過DataAdpater對象的Update方法 

          DataAdapter對象的update方法可以調用來講Dataset中的更改解析回資料源。其工作原理本質上還是通過執行所引用的Command對象進行更新的。當調用Update方法的時候,DataAdpater将分析出已經發生的變化,并執行相應的指令(insertCommand、updateCommand或者deleteCommand)。是以,要提供性能,就要盡可能的顯示設定DataAdpater的指令。 

           當然,如果DataTable映射到單個資料表上,或者它是由單個表填充生産的,也可以利用CommandBuilder對象自動生成DataAdapter的DeleteCommand、InsertCommand和UpdateCommand。其方法是:先生成SqlCommandBuilder對象:SqlCommandBuilder scb=new SqlCommandBuilder(sqlDataAdpater);這樣,就能夠自動通過CommandBuilder來設定擴充卡sqlDataAdapter的指令形式:類似于sqlDataAdpter.UpdateCommand=scb.getUpdateCommand()   。 

          如果使用OleDb、Odbc、Oracle連接配接資料庫,隻需要做相應的調整就行了。 

          在使用CommandBuilder為DataAdapter生成Command指令更新資料源時,需要注意以下事項: 

1、SelectCommand使用的select指令中必須包含主鍵(其實在資料表中如果聲明了主鍵即可) 

2、填充資料集時,必須要加載主鍵。方法如下: 

             da.Fill(ds, "dataTableName"); 

             ds.Tables["dataTableName"].PrimaryKey=new DataColumns[]{ds.Tables["dataTableName"].Columns["ColulmnsName"]}; 

        或者也可以這麼做: 

            da.FillSchema(ds, SchemaType.Source, "dataTableName");      //加載表結構 

            da.Fill(ds, "dataTableName");                                                      //加載表資料 

3、DataAdapter的MissingSchemaAction屬性設定為AddWithKey 

4、更新資料源成功後,使用ds的Acceptchanges方法,更新資料集。 

          二、通過Command對象進行更新 

下面舉個使用擴充卡進行資料更新的例子。 

首先,為了不破壞了SQL2005上原有的示例資料庫的資料,我們先使用“select * into salesreason from sales.salesreason”,将sales.salesreason表複制一份到dbo.salesreson中去。然後就對dbo.salesreson進行操作。下面是界面設計圖。 

幾個控件:customerid後面的的文本框 textBox1,下面分别是textBox2、textBox3以及右下角的textBox4. 

幾個按鈕:“資料插入”名為button1,下面依次是button2、button3;“< <”是button4,右邊依次是5/6/7 

“查找”是button8. 

下面是詳細代碼: 

using System; 

using System.Collections.Generic; 

using System.ComponentModel; 

using System.Data; 

using System.Drawing; 

using System.Text; 

using System.Windows.Forms; 

using System.Data.SqlClient; 

namespace WindowsApplication1 

    public partial class Form1 : Form 

    { 

        int i = 0; //用i來确定其坐在資料表的行号。一開始時i=0,則是表中的第一行 

        DataSet ds; 

        SqlDataAdapter sda; 

        string strcon = "Data Source=localhost; Initial Catalog=adventureWorks; Integrated Security=sspi"; 

        string strsql = "select SalesReasonID,name,ReasonType from dbo.SalesReason"; 

        SqlConnection scon; 

        public Form1() 

        { 

            InitializeComponent(); 

        } 

        private void Form1_Load(object sender, EventArgs e) 

            scon = new SqlConnection(strcon); 

        public void show(int i) 

            if (ds != null) 

            { 

                ds.Clear(); 

            } 

            else 

                ds = new DataSet(); 

                sda = new SqlDataAdapter(strsql,strcon); 

            sda.Fill(ds, "SalesReason"); 

            textBox1.Text = ds.Tables["SalesReason"].Rows[i]["SalesReasonID"].ToString(); 

            textBox2.Text = ds.Tables["SalesReason"].Rows[i]["Name"].ToString(); 

            textBox3.Text = ds.Tables["SalesReason"].Rows[i]["ReasonType"].ToString(); 

        private void button4_Click(object sender, EventArgs e) 

            i = 0; 

            show(i); 

        private void button5_Click(object sender, EventArgs e) 

            if (i != 0) 

                i--; 

                show(i); 

                MessageBox.Show("已經是第一條記錄了"); 

        private void button6_Click(object sender, EventArgs e) 

            if (i < ds.Tables["SalesReason"].Rows.Count - 1) 

                i++; 

                MessageBox.Show("已經是最後一條記錄了"); 

        private void button7_Click(object sender, EventArgs e) 

            i=ds.Tables["SalesReason"].Rows.Count - 1; 

        private void button8_Click(object sender, EventArgs e) 

            int k = 0;//用來确定要查找記錄的下标 

            if (textBox4.Text.Trim() == "") 

                MessageBox.Show("查找内容不能為空"); 

                for (k = 0; k < ds.Tables["SalesReason"].Rows.Count; k++) 

                { 

                    if (ds.Tables["SalesReason"].Rows[k]["SalesReasonID"].ToString() == textBox4.Text) 

                    {//找到了和textBox4中的id号相比對的記錄了,其行号為k 

                        i = k; 

                        show(i); 

                        break; 

                    } 

                } 

            if (k == ds.Tables["SalesReason"].Rows.Count) 

                MessageBox.Show("無此客戶資訊"); 

            textBox4.Text = ""; 

        private void button1_Click(object sender, EventArgs e) 

            SqlCommand sqlcmd = new SqlCommand("select count(*) from sales.SalesReason where SalesReasonID='" + textBox1.Text + "'", scon); 

            sqlcmd.Connection.Open(); 

            int a = (int)sqlcmd.ExecuteScalar();//傳回源表中與輸入的客戶id相等的個數 

            sqlcmd.Connection.Close(); 

            if (a > 0) 

                MessageBox.Show("此客戶已經存在,請重新插入"); 

                return; 

            ds.Clear(); 

            ds.Tables["SalesReason"].PrimaryKey = new DataColumn[] { ds.Tables["SalesReason"].Columns["SalesReasonID"] }; 

            SqlCommandBuilder sqlCommandBuilder1 = new SqlCommandBuilder(sda); 

            DataRow dr = ds.Tables["SalesReason"].NewRow(); 

            dr["SalesReasonID"] = Int32.Parse(textBox1.Text); 

            dr["name"] = textBox2.Text; 

            dr["ReasonType"] = textBox3.Text; 

            ds.Tables["SalesReason"].Rows.Add(dr); 

            sda.Update(ds, "SalesReason"); 

            ds.AcceptChanges(); 

            MessageBox.Show("資料插入成功"); 

        private void button2_Click(object sender, EventArgs e) 

            for (int j = 0; j < ds.Tables["SalesReason"].Rows.Count; j++) 

                if (ds.Tables["SalesReason"].Rows[j]["SalesReasonID"].ToString() == "" && 

                    ds.Tables["SalesReason"].Rows[j]["SalesReasonID"].ToString() != ds.Tables["SalesReason"].Rows[i]["SalesReasonID"].ToString()) 

                    MessageBox.Show("此SalesReasonid已經存在,請重新輸入"); 

                    textBox1.Text = ""; 

                    return; 

            ds.BeginInit(); //挂起修改資料 

            ds.Tables["SalesReason"].Rows[i]["SalesReasonID"] = Int32.Parse(textBox1.Text); 

            ds.Tables["SalesReason"].Rows[i]["Name"] = textBox2.Text; 

            ds.Tables["SalesReason"].Rows[i]["ReasonType"] = textBox3.Text; 

            ds.EndInit(); //結束挂起 

            MessageBox.Show("資料修改成功"); 

        private void button3_Click(object sender, EventArgs e) 

            DataSet ds = new DataSet(); 

            SqlDataAdapter da = new SqlDataAdapter(strsql,strcon); 

            da.Fill(ds, "SalesReason"); 

            SqlCommandBuilder sqlCommandBuilder1 = new SqlCommandBuilder(da); 

         //   da.DeleteCommand = sqlCommandBuilder1.GetDeleteCommand(); 

            ds.Tables["SalesReason"].Rows[i].Delete(); 

            da.Update(ds,"SalesReason"); 

            MessageBox.Show("資料删除成功"); 

            show(i);//删除成功後,重新顯示第一條資料 

    } 

如果使用SQL Command的方式來直接更新資料源,寫起來就更簡單了,舉個例子,拿前面删除部分的例子來舉例好了: 

             SqlCommand cmd=new SqlCommand(); 

             cmd.Connection=scon; 

             cmd.CommandText="delete from dbo.SalesReason where SalesReasonID=' "+textBox1.Text+" ' "; 

             scon.Open(); 

            cmd.ExecuteNonQuery(); 

            scon.Close();      //更新完畢,下面代碼重新整理顯示,将記錄定位到第一行 

            i=0;        refresh(); 

             MessageBox.Show("資料删除成功"); 

            refresh();