1. 程式人生 > >ADO.NET系列之DataAdapter物件

ADO.NET系列之DataAdapter物件

 

     我們前兩篇文章介紹了ADO.NET的概念,以及介紹了Connection和Command物件,基本的增刪改查操作都能夠實現了,本節再介紹一個強大的DataAdapter物件。

     我們先來看看DataAdapter物件的工作原理如下圖所示:

    DataAdapter首先將構造一個SelectCommand例項(本質就一個Command物件),然後檢查是否開啟連線,如果沒有開啟連線則開啟連線,緊接著呼叫DataReader介面檢索資料,最後根據維護的對映關係,將檢索到得資料庫填充到本地的DataSet或者DataTable中。同理,我們需要更新資料來源時,DataAdatper則將本地修改的資料,跟據對映關係,構造InsertCommand,UpdateCommnad,DeleteCommand物件,然後執行相應的命令。

     為什麼說DataAdapter物件強大呢?首先DataAdapter物件可以執行查詢操作,嚴格意義上也不是執行,而是可以填充DataSet,DataTable物件,再一個DataAdapter物件可以進行批量更新和批量刪除,至於批量新增我們有SqlBulkCopy物件,後面文章會介紹SqlBulkCopy物件。

       DataAdapter.Net提供了四種Connection 物件:

  1.   針對Sql Server的SqlDataAdapter,位於名稱空間System.Data.SqlClient下
  2.   針對Oledb連結的OledbDataAdapter,位於名稱空間System.Data.Oledb下
  3.   針對MySql的MySqlDataAdapter,位於名稱空間System.Data.MySqlClient下(需要引用MySql.Data.dll)
  4.   針對Oracle的OracleDataAdapter,位於名稱空間Oracle.ManagedDataAccess.Client(需引用Oracle.ManagedDataAccess.dll)

     我們先來看看DataAdapter物件填充DataSet,DataTable物件的示例: 

  string connectionString = "Data Source=.;Initial Catalog=ax_log;User Id=sa;Password=sa123;";
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                string sql = "select * from eftest where [email protected]";
                SqlParameter para = new SqlParameter("@id", 1);
                using (SqlCommand com = new SqlCommand(sql, con))
                {
                    DataSet ds = new DataSet();
                    try
                    {
                        com.Parameters.Add(para);
                        con.Open();
                        SqlDataAdapter adapter = new SqlDataAdapter(com);
                        adapter.Fill(ds);
                        foreach (DataRow s in ds.Tables[0].Rows)
                        {
                            Console.WriteLine("ID:"+s["id"].ToString());
                            Console.WriteLine("Name:" + s["name"].ToString());
                        }
                    }
                    catch (Exception ex)
                    { }
                }
            }

DataAdapter物件實現批量修改

string connectionString = "Data Source=.;Initial Catalog=ax_log;User Id=sa;Password=sa123;";
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                string sql = "select * from eftest ";
                DataSet ds = new DataSet();
                try
                {
                    con.Open();
                    SqlDataAdapter adapter = new SqlDataAdapter(sql, con);
                    adapter.Fill(ds);//填充ds
                    for (int k = 0; k < ds.Tables[0].Rows.Count; k++)
                    {
                        Console.WriteLine(ds.Tables[0].Rows[k].RowState);//RowState:Unchanged 
                        Console.WriteLine(ds.Tables[0].Rows[k][1]);
                        ds.Tables[0].Rows[k][1] = "abc";//每一行的第二列都修改為abc
                        Console.WriteLine(ds.Tables[0].Rows[k][1]);
                        Console.WriteLine(ds.Tables[0].Rows[k].RowState);//RowState:Modified 
                    }
                    SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(adapter);//這行不能缺少,除非自定義Command賦值給adapter.UpdateCommand
                    Console.WriteLine("生成的Update語句:{0}", cmdBuilder.GetUpdateCommand().CommandText);
                    adapter.Update(ds);//更新到資料來源中
                    ds.AcceptChanges();//提交到DataTable中  提交後DataRow.RowState會修改為Unchanged
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }

根據上程式碼,我們先要介紹下DataRow.RowState屬性,DataRowState是一個列舉型別:

 //
        // 摘要:
        //     該行已被建立,但不屬於任何 System.Data.DataRowCollection。System.Data.DataRow 在以下情況下立即處於此狀態:建立之後新增到集合中之前;或從集合中移除之後。
        Detached = 1,
        //
        // 摘要:
        //     該行自上次呼叫 System.Data.DataRow.AcceptChanges 以來尚未更改。
        Unchanged = 2,
        //
        // 摘要:
        //     該行已新增到 System.Data.DataRowCollection 中,System.Data.DataRow.AcceptChanges 尚未呼叫。
        Added = 4,
        //
        // 摘要:
        //     該行已通過 System.Data.DataRow 的 System.Data.DataRow.Delete 方法被刪除。
        Deleted = 8,
        //
        // 摘要:
        //     該行已被修改,System.Data.DataRow.AcceptChanges 尚未呼叫。
        Modified = 16

   我們可以根據RowState屬性可以很清楚的知道DataTable中的每一行資料是新增的?修改過?刪除了?還是未曾改變! 其實adapter.Update(ds)更新資料也是根據這個屬性批量向資料來源更新的。

DataAdapter實現批量新增和批量刪除都是大同小異,只是操作DataTable新增或者刪除就行了。