1. 程式人生 > >ADO .NET總結

ADO .NET總結

ADO .NET主要用到了:

  1. SqlConnection-連線資料庫
  2. SqlCommand-執行SQL語句或者儲存過程
  3. SqlDataReader-執行SQL語句後資料儲存於該資料流中
  4. SqlDataAdapter-將資料儲存在DataSet中

外加幾個涉及到安全的類:

  1. SqlConnectionStringBuilder-生成連線字串
  2. SqlParameter-用引數的形式組裝SQL語句

具體可以查閱MSDN ADO相關頁面,下面是例項:

首先建立一個測試資料庫:

create database students

use students

create table stu(
 id int,
 name varchar(10),
 sex char(2)
)

insert into stu(id, name, sex)
values(1,'小明','女')

1.連線資料庫

SqlConnection用來連線資料庫,這是一切的開始,主要用到兩個方法

  • Open()連線資料庫
  • Close()關閉資料庫連線,這是必須的。

建立一個c#控制檯程式,例項程式碼都會在這裡面完成

引入名稱空間

using System.Data.SqlClient;

連線資料庫需要連線字串,連線SQL Server的字串一般格式為

  • Data Source=計算機名或者IP地址;Initial Catalog=資料庫名;User ID=登入ID;Password=密碼;

 在控制檯程式中新增一個連線資料庫的方法,並在Main中呼叫

        static void Main(string[] args)
        {
            conDataBase();

            Console.Read();
        }

        public static void conDataBase()
        {
            using (SqlConnection con = new SqlConnection("Data Source=你的電腦名;Initial Catalog=students;User ID=你的ID;Password=你的密碼;"))
                
            {
                try
                {
                    con.Open();
                    Console.Write("資料庫連線成功!");
                }

                catch
                {
                    Console.Write("資料庫連線失敗!");
                }
            }
        }

利用using語句可以自動釋放相關資源,如果不使用using需要con.Close()方法關閉連線。執行結果:

這樣就成功連線到了資料庫,下面便是對資料庫執行操作。

2.SqlCommand && DataReader

  SqlCommand一般用到下面幾個方法:

命令 返回值
ExecuteReader 執行查詢,返回一個 DataReader 物件。
ExecuteScalar 執行查詢,並返回由查詢返回的結果集中的第一行的第一列,其他列或行將被忽略。
ExecuteNonQuery 一般執行增刪改語句,返回受影響行數

一般用到的屬性有: 

Connection

獲取或設定 SqlCommand 的此例項使用的 SqlConnection

CommandText

獲取或設定要在資料來源中執行的 Transact-SQL 語句、表名或儲存過程。

可以直接用相關建構函式去宣告一個SqlCommand類,省去了設定上面兩個屬性:SqlCommand("SQL語句","SqlConnection物件");

DataReader是一個只能讀取且只能前進的資料流,用read()方法讀取下一個資料。不能直接建立一個DataReader物件,必須通過SqlCommand的ExecuteReader方法來構建一個DataReader物件。最後也必須使用Close()關閉Reader流。

ExecuteReader例項:

新增一個方法,並在Main中呼叫:

        public static void DataReader()
        {
            using (SqlConnection con = new SqlConnection("Data Source=你的電腦名;Initial Catalog=students;User ID=你的ID;Password=你的密碼;"))
            {
                try
                {
                    SqlCommand com = new SqlCommand("select * from stu", con);
                    con.Open();
                    SqlDataReader read = com.ExecuteReader();
                    while(read.Read())
                    {
                        Console.WriteLine(read["id"].ToString() + " - " + read["name"].ToString()+ " - " + read["sex"].ToString());
                    }
                }

                catch (Exception ex)
                {
                    Console.Write(ex);
                }
            }
        }

執行結果:

ExecuteNonQuery例項:

        public static void UpDateDateBase()
        {
            using (SqlConnection con = new SqlConnection("Data Source=你的電腦名;Initial Catalog=students;User ID=你的ID;Password=你的密碼;"))
            {
                try
                {
                    con.Open();
                    //插入一條資料
                    SqlCommand com = new SqlCommand("insert into stu(id, name, sex) values(2,'小紅','男')", con);
                    int i = com.ExecuteNonQuery();
                    Console.WriteLine("更新了{0}條資料",i);

                    //列印目前的資料
                    com.CommandText = "select * from stu";
                    SqlDataReader read = com.ExecuteReader();
                    while(read.Read())
                    {
                        Console.WriteLine(read["id"].ToString() + " - " + read["name"].ToString() + " - " + read["sex"].ToString());
                    }
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }

 執行結果:

ExecuteScalar 例項:

ExecuteScalat方法返回單個值,該值是一個Object型別,需要進行轉換

        public static void DataScalar()
        {
            using (SqlConnection con = new SqlConnection("Data Source=你的電腦名;Initial Catalog=students;User ID=你的ID;Password=你的密碼;"))
            {
                try
                {
                    SqlCommand com = new SqlCommand("select name from stu where id = 1", con);
                    con.Open();
                    string name = com.ExecuteScalar().ToString();
                    Console.Write(name);
                }

                catch (Exception ex)
                {
                    Console.Write(ex);
                }
            }
        }

執行結果:

3.SqlParameter

上面的例項中都是直接寫死了一個SQL查詢語句,實際上並不會這樣用,都是接受引數去組成SQL語句的Where部分,可能有的人直接用拼接字串的方法來組成SQL語句,不過這樣做會有風險,舉個例子:

        public static void DataReader(string id)
        {
            using (SqlConnection con = new SqlConnection("Data Source=你的電腦名;Initial Catalog=students;User ID=你的ID;Password=你的密碼;"))
            {
                try
                {
                    SqlCommand com = new SqlCommand("select * from stu where id = " + id, con);
                    con.Open();
                    SqlDataReader read = com.ExecuteReader();
                    while(read.Read())
                    {
                        Console.WriteLine(read["id"].ToString() + " - " + read["name"].ToString()+ " - " + read["sex"].ToString());
                    }
                }

                catch (Exception ex)
                {
                    Console.Write(ex);
                }
            }
        }

將上面的例子改為接收一個id引數去查詢資料庫,當引數是正常填入,比如1,這個方法沒有任何問題,輸出:這也是我們想要的效果,不過如果在引數上動點手腳,情況就不一樣了,將傳入的引數改為:

DataReader("'' or 1 = 1");

執行結果:這下子我們的資料全部暴露出來了,這種方式就是SQL注入。

可疑利用SqlParameter避免這種情況,用SqlParameter改造上面的例子:

        public static void DataReader(string id)
        {
            using (SqlConnection con = new SqlConnection("Data Source=你的電腦名;Initial Catalog=students;User ID=你的ID;Password=你的密碼;"))
            {
                try
                {
                    SqlCommand com = new SqlCommand("select * from stu where id = @id", con);
                    SqlParameter _id = new SqlParameter("@id",id);
                    com.Parameters.Add(_id);
                    /*也可以寫成
                    com.Parameters.Add(new SqlParameter("@id", id));
                    */
                    con.Open();
                    SqlDataReader read = com.ExecuteReader();
                    while(read.Read())
                    {
                        Console.WriteLine(read["id"].ToString() + " - " + read["name"].ToString()+ " - " + read["sex"].ToString());
                    }
                }

                catch (Exception ex)
                {
                    Console.Write(ex);
                }
            }
        }

這個時候引數輸入'' or 1 = 1就會發生錯誤,從而避免了被注入攻擊。

當有多個引數的時候,可以寫多個com.Parameters.Add()方法或者建立Parameters陣列與AddRange()方法,例:

                    SqlParameter[] parameter = new SqlParameter[] 
                    {
                        new SqlParameter("@id", id),
                        new SqlParameter("@name", "小明")
                    };
                    com.Parameters.AddRange(parameter);

4.SqlDataAdapter && DataSet

SqlDataAdapter主要用來將資料填充到DataSet中

主要屬性有:

SelectCommand

獲取或設定一個 TRANSACT-SQL 語句或儲存的過程用於在資料來源中選擇記錄。

主要方法有:

Fill(DataSet)

在 DataSet 中新增或重新整理行。

(Inherited from DbDataAdapter)

DataSet並不單單用於儲存資料庫中查詢出來的資料,不過這裡並不討論其它情況,就只說資料庫的內容。

程式碼奉上:

        public static void DataSet()
        {
            using (SqlConnection con = new SqlConnection("Data Source=你的電腦名;Initial Catalog=students;User ID=你的ID;Password=你的密碼;"))
            {
                try
                {
                    con.Open();
                    SqlCommand com = new SqlCommand("select * from stu", con);
                    SqlDataAdapter da = new SqlDataAdapter();
                    da.SelectCommand = com;
                    DataSet ds = new DataSet();

                    da.Fill(ds);

                    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                    {
                        Console.WriteLine(ds.Tables[0].Rows[i]["id"].ToString() + " - " + ds.Tables[0].Rows[i]["name"].ToString() + " - " + ds.Tables[0].Rows[i]["sex"].ToString());
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }

最後可以將上面的幾個方法整理一下,使其成為一個類庫,就可以較為方便地操作資料庫。