ADO.NET隨筆

平常在Service會使用到的ado.net ,有可以用DataReader或用DataSet的方式,這邊紀錄使用方法

 

範例都用北風資料庫操作,沒有的請去這裡下載
https://onedrive.live.com/?authkey=%21AEZb2lql49fYT78&cid=7C5615A2345B2795&id=7C5615A2345B2795%21722348&parId=7C5615A2345B2795%21335787&o=OneUp

ADo.NET連結資料庫的步驟

1.連接資料庫(ConnetString)

2.寫SQL指令存取資料(讀取或寫入)  CRUD

3.WebForm可以DataBind() 或把資料取出來轉成List做處理

4.關閉資源

簡單說就是Connect>CRUD>Bind>Close

 

連接字串可以用sqldatasource控制項連接,連好之後會在web.config出現一段

<connectionStrings>
    <add name="NorthwindConnectionString" connectionString="Data Source=(localdb)\Sampledb;Initial Catalog=Northwind;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

Initial Catalog:資料庫名稱

Data Source:連接資料庫的伺服器名稱 (.是本機)

如果有帳號密碼的話要加上User ID=XXX;Password=XXX

在頁面上連接的話可以如下寫法

using System.Web.Configuration;

using System.Data.SqlClient;

 SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);

 

 

ADO.NET有兩個重點分別是DataAdaper跟DataReader,DataReader是從資料來源讀取順向且唯獨的資料流,DataAdaper是把資料填到DataSet,或是更新後的資料回填到資料來源

以下做個表格比較

  DataAdaper DataReader
連結資料庫 不用,會自動開啟關閉 SqlConnection.Open()
執行SQL指令

SqlDataAdapter

.Fill()

.Open()

SqlCommand

ExecuteReader()

ExecuteNonQuery()

資料指標移動 讀到記憶體裡 順向且唯獨
如何處理資料 可以處理複雜資料庫關聯跟多個DataTable 適合單一資料表
消耗資源 較大 較小
分頁

以上表格來自ASP.NET專題實務

1.DataReader

只提供唯獨且順向的資料,就是只會一行一行一直往下讀,沒有辦法往上回溯

只要執行Read()方法,每讀完一筆資料就會把指標指向下一筆,

範例

 SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);
            SqlDataReader dr = null;

            SqlCommand cmd=new SqlCommand();
            cmd.CommandType = System.Data.CommandType.Text;
            cmd.CommandTimeout = 300;
            cmd.Connection = conn;
            cmd.CommandText = "SELECT * FROM [Suppliers] ORDER BY [CompanyName]";

            try
            {
                conn.Open();
                dr = cmd.ExecuteReader();
                //資料繫結或做其他處理
                GridView1.DataSource = dr;
                GridView1.DataBind();
            }
            catch(Exception ex)
            {
                throw ex;
             }
            finally//關閉資源
            {
                if (dr != null)
                {
                    cmd.Cancel();
                    dr.Close();
                }
                if (conn.State == System.Data.ConnectionState.Open)
                {
                    conn.Close();
                    conn.Dispose();

                }

            }

記得要先呼叫SqlCommand的.Cancel()方法在呼叫DataReader.Close()方法,否則會浪費資源喔!

也可以用using自動關閉資源,這樣就不用呼叫Close()方法了

 

2.DataAdaper

範例

SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);
            SqlDataAdapter da = null;
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = System.Data.CommandType.Text;
            cmd.CommandTimeout = 300;
            cmd.Connection = conn;
            cmd.CommandText = "SELECT * FROM [Suppliers] ORDER BY [CompanyName]";
            da = new SqlDataAdapter(cmd);
            DataSet ds = new DataSet();
            da.Fill(ds);//把資料庫資料填入到DataSet
            //資料繫結
            GridView1.DataSource = ds;
            GridView1.DataBind();

填入DataSet之後不一定要直接做資料繫結,如果是MVC,可以取出來做一些處理,例如篩選資料或判斷條件,可以用Linq to DataSet,個人用過覺得算很好用,也可以把DataSet透過反射轉成List

 

3.ADO.NET 使用預存程序

其實這算是公司內用最多的一種方式了,因為不一定每個RD SQL都很強,所以有些公司會請DBA(資料庫管理師)負責開資料庫Table,複雜的邏輯也會由DBA那邊寫好Store Procedure,我們RD就直接call就好了,也不失為一個方便的方式,只是debug的時候會需要判斷是RD程式錯還是SP錯

先來個範例吧

 SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);
            SqlCommand cmd = new SqlCommand("自己寫的預存程序", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandTimeout = 300;
            cmd.Parameters.Add("@StartDate", SqlDbType.VarChar, 8).Value = StartDate;
            cmd.Parameters.Add("@EndDate", SqlDbType.VarChar, 8).Value = EndDate;
            cmd.Parameters.Add("@Type", SqlDbType.Int).Value = Type; 
            cmd.Parameters.Add("@Account", SqlDbType.VarChar, 6).Value = Account;
            SqlParameter Price = new SqlParameter("@myValue", SqlDbType.Decimal);
            Price.Precision = 18;
            Price.Scale = 2;
            cmd.Parameters.Add(Price);

            SqlParameter ReturnMsg = cmd.Parameters.Add("@ReturnMsg", SqlDbType.NVarChar, 15);
            ReturnMsg.Direction = ParameterDirection.Output;
            
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataSet ds = new DataSet();
            try
            {

                conn.Open();
                da.Fill(ds);
            }
            catch (Exception ex)
            {
                throw ex;
               
            }
            finally
            {
                conn.Close();
            }

比較特別的應該是參數的型別,decimal要去另外設定他的總位元數跟小數後幾位,如果是DataTime型別的,則依定要轉型成SQL可以讀的DateTime格式

今天就先分享到這邊吧