ADO.NET- 基礎總結及實例


1、ADO.NET基礎介紹

 (1、程序要和數據庫交互要通過ADO.NET進行,通過ADO.NET就能在程序中執行SQL了。ADO.Net中提供了對各種不同數據庫的統一操作接口。

   (2、直接在項目中內嵌mdf文件的方式使用SQL Server數據庫(基於服務的數據庫)。mdf文件隨着項目走,用起來方便,和在數據庫服務器上創建數據庫沒什么區別,運行的時候會自動附加(Attach)。

 (3、雙擊mdf文件會在“服務器資源管理器”中打開,管理方式和在Mnagemen Studio沒什么本質不同,要拷貝mdf 文件需要關閉所有指向mdf文件的連接。

 (4、正式生產運行的時候附加到SQLServer上、修改連接字符串即可,除此之外沒有任何的區別,在“數據庫”節點上點右鍵“附加”;在數據庫節點上à任何à分離 就可以得到可以拷來拷去mdf 文件。

 (5、用的時候要在控制台、WinForm項目中的Main函數最開始的位置加入“一段神奇的代碼"。ASP.Net項目中不需要

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Data.SqlClient;
 6 
 7 namespace myadonet
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             //神奇代碼
14             string dateDir = AppDomain.CurrentDomain.BaseDirectory;
15             if (dateDir.EndsWith(@"\bin\Debug\")
16                 || dateDir.EndsWith(@"\bin\Release\"))
17             {
18                 dateDir = System.IO.Directory.GetParent(dateDir).Parent.Parent.FullName;
19                 AppDomain.CurrentDomain.SetData("DataDirectory", dateDir);
20             }
21 
22             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"))
23             {
24                 conn.Open();
25 
26             Console.WriteLine("連接成功!");
27             Console.ReadKey();
28         }
29     }
30 }

 

2、連接到SQLServer數據庫

       (1、連接字符串:程序通過連接字符串 指定要連哪台服務器上的、哪個實例的哪個數據庫、用什么用戶名 密碼等。

       (2、項目內嵌mdf文件形式的連接字符串“Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Inte grated Security=True;User Intance=True”。“.SQLEXPRESS”表示本機上的SQLEXPRESS實例,如果數據庫實例名不是SQLEXPRESS,則需要修改。  Database1.mdf”為mdf的文件名。

       (3、ADO.Net中通過SQLConnection在創建SQLServer的連接,SQLConnection代表一個數據庫連接,ADO.Net中的連接等資源都實現了IDisposable接口,可以使用using進行資源管理。執行這段段代碼,如果成功了就OK

       (4、在實現了IDisposable接口的對象,在使用完后需要用行資源釋放

 

3、執行簡單的Insert語句

    (1、SQLCommand表示向服務器提交的一個命令(SQL語句等)。

      (2、CommandText屬性為要執行的SQL語句,Execute NonQuery方法執行一個非查詢語句UpdateinsetDelete等)

     (3、ExecuteNonQuery返回值是執行的影響行數

在conn.open();下面敲上這樣一段代碼即可插入數據庫數據:

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Data.SqlClient;
 6 
 7 namespace myadonet
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             //神奇代碼
14             string dateDir = AppDomain.CurrentDomain.BaseDirectory;
15             if (dateDir.EndsWith(@"\bin\Debug\")
16                 || dateDir.EndsWith(@"\bin\Release\"))
17             {
18                 dateDir = System.IO.Directory.GetParent(dateDir).Parent.Parent.FullName;
19                 AppDomain.CurrentDomain.SetData("DataDirectory", dateDir);
20             }
21 
22             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"))
23             {
24                 conn.Open();
25                 /* 插入數據* */
26                 using (SqlCommand commd = conn.CreateCommand()) {
27                     commd.CommandText = "Insert into T_UserInfo (sUser,sPassWord) values('admin','888888')";
28                     commd.ExecuteNonQuery();
29                     Console.WriteLine("插入成功");
30                 }
31                  
32 
33             }
34 
35             Console.WriteLine("連接成功!");
36             Console.ReadKey();
37         }
38     }
39 }

 

4、模擬登陸

同樣在conn.open();下面敲上這樣一段代碼即可

View Code
 1  bool flag = true;
 2                 while (flag)
 3                 {
 4                     Console.WriteLine("請輸入用戶名:");
 5                     string sUser = Console.ReadLine();
 6                     using(SqlCommand cmd=conn.CreateCommand()){
 7                         cmd.CommandText = "Select * from T_UserInfo where sUser='"+sUser+"'";
 8                         using (SqlDataReader reader = cmd.ExecuteReader()) {
 9                             if (reader.Read())
10                             {
11                                 Console.WriteLine("請輸入密碼:");
12                                 string sPassWord = Console.ReadLine();
13                                 string QueryPassWord=reader.GetString(reader.GetOrdinal("sPassWord"));
14                                 if (sPassWord == QueryPassWord)
15                                 {
16                                     Console.WriteLine("登陸成功!");
17                                     flag = false;
18                                 }
19                                 else {
20                                     Console.WriteLine("密碼錯誤");
21                                 }
22                             }
23                             else { Console.WriteLine("用戶不存在,請重新輸入"); }
24                         }
25                     }
26                 }

 

5、ExecuteScalar

      (1、SqlCommand中的ExecuteScalar方法用於執行查詢,並返回查詢所返回的結果集中第一行的第一列,因為不能確定返回值的類型,所以,ExecuteScalar的返回值為object類型

     (2、得到自動增長字段的主鍵值,在values關鍵詞前加上output inserted.Id,其中Id為主鍵字段名。執行結果就是插入的主鍵值,用ExecuteScalar執行最方便。

 

View Code
 1  using (SqlCommand cmd = conn.CreateCommand())
 2                 {
 3                     cmd.CommandText = "Select * from T_UserInfo";                        
 4                     using (SqlDataReader reader = cmd.ExecuteReader())
 5                     {
 6                         while (reader.Read()) //這里得到一個bool值
 7                         {
 8                             string sUser = reader.GetString(reader.GetOrdinal("sUser"));
 9                             //int ID = reader.GetInt32(reader.GetOrdinal("ID"));
10                             string sPassWord = reader.GetString(reader.GetOrdinal("sPassword"));       //多行結果集
11                             Console.WriteLine("{0}{1}", sUser, sPassWord);
12 
13                         }
14                     }
15                 }

 

 (3、執行有多行結果集的用 ExecuteReader:讀到最后一條數據返回false

          readerGetStringGetInt32等方法只接受整數參數,也就是序號,用GetOrdinal方法根據列名動態得到序號了。

View Code
 1  /*最佳登陸方式*/
 2                 bool flag = true;
 3                 while (flag)
 4                 {
 5                     Console.WriteLine("請輸入用戶名:");
 6                     string sUser = Console.ReadLine();
 7                     using (SqlCommand cmd = conn.CreateCommand())
 8                     {
 9                         cmd.CommandText = "Select * from T_UserInfo where sUser='" + sUser + "'";
10                         using (SqlDataReader reader = cmd.ExecuteReader())
11                         {
12                             if (reader.Read())
13                             {
14                                 Console.WriteLine("請輸入密碼:");
15                                 string sPassWord = Console.ReadLine();
16                                 string QueryPassWord = reader.GetString(reader.GetOrdinal("sPassWord"));
17                                 if (sPassWord == QueryPassWord)
18                                 {
19                                     Console.WriteLine("登陸成功!");
20                                     flag = false;
21                                 }
22                                 else
23                                 {
24                                     Console.WriteLine("密碼錯誤");
25                                 }
26                             }
27                             else { Console.WriteLine("用戶不存在,請重新輸入"); }
28                         }
29                     }
30                 }

 

6、為什么用using       

         Close:關閉以后還能打開。  Dispose:直接銷毀,不能再次使用。

         Using在出了作用域以后調用DisposeSqlConnection FileStream 等的Dispose內部都會做這樣的判斷:判斷有沒有close,如果沒有,就

CloseDispose

7、SQL注入漏洞攻擊/參數化查詢

       **例如第4點所說的登錄判斷:select count(*) from T_Users where sUser=…and Password=…,將參數拼到SQL語句中。

           我們可以通過構造惡意的sPassword輸入     1`or`1`=`1

           編譯通過后識別出來的就是:select count(*) from T_Users where sUser= ‘admin’ and Password=‘1`or`1`=`1’

      **參數化查詢解決漏洞攻擊

           SQL語句使用@sUser表示“此處用參數代替”,向SqlCommandParameters中添加參數。

View Code
1 cmd.CommandText = "select count(*)from T_Users where sUser =@UN and sPassword=@PW";
2 
3 cmd.Parameters.Add(new SqlParameter("UN", sUser));
4 
5 cmd.Parameters.Add(new SqlParameter("PW", sPassword));

 

           參數在SQLServer內部不是簡單的字符串替換,SQLServer直接用添加的值進行數據比較,因此不會有注入漏洞攻擊。

 8、模擬窗體登陸,並且設置登陸錯誤次數

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using System.Data.SqlClient;
10 
11 namespace myAdoNet02
12 {
13     public partial class Form1 : Form
14     {
15         public Form1()
16         {
17             InitializeComponent();
18         }
19 
20         private void IntsErrorTime()
21         {
22             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;  
23             Integrated Security=True;Connect Timeout=30;User Instance=True"))
24             {
25                 conn.Open();
26                 using (SqlCommand cmd = conn.CreateCommand())
27                 {
28                     using (SqlCommand updateCmd = conn.CreateCommand())
29                     {
30                         //假如用戶輸入的用戶名和密碼錯誤次數過多,則將數據庫中的錯誤記錄次數加1  
31                         updateCmd.CommandText = "update T_UserInfo Set sErrorTime=sErrorTime+1 where sUser=@sUser";
32                         updateCmd.Parameters.Add(new SqlParameter("sUser", textBox1.Text));
33                         updateCmd.ExecuteNonQuery();
34                     }
35                 }
36             }
37         }
38         private void ResetsErrorTime()
39         {
40             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\UsersDB.mdf;  
41             Integrated Security=True;Connect Timeout=30;User Instance=True"))
42             {
43                 conn.Open();
44                 using (SqlCommand cmd = conn.CreateCommand())
45                 {
46                     using (SqlCommand updateCmd = conn.CreateCommand())
47                     {
48                         //假如用戶輸入的用戶名和密碼均正確,則將數據庫的錯誤次數歸0,重新統計。  
49                         updateCmd.CommandText = "update T_UserInfo Set sErrorTime=0 where sUser=@sUser";
50                         updateCmd.Parameters.Add(new SqlParameter("sUser", textBox1.Text));
51                         updateCmd.ExecuteNonQuery();
52                     }
53                 }
54             }
55         }
56         private void button1_Click(object sender, EventArgs e)
57         {
58             using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\UsersDB.mdf;  
59             Integrated Security=True;Connect Timeout=30;User Instance=True"))
60             {
61                 conn.Open();
62                 using (SqlCommand cmd = conn.CreateCommand())
63                 {
64                     cmd.CommandText = "Select * from T_UserInfo where sUser=@sUser";//加"@"參數化查詢  
65                     cmd.Parameters.Add(new SqlParameter("sUser", textBox1.Text));
66                     using (SqlDataReader reader = cmd.ExecuteReader())
67                     {
68                         if (reader.Read())
69                         {
70                             int errorTimes = reader.GetInt32(reader.GetOrdinal("sErrorTime"));
71                             if (errorTimes > 3)
72                             {
73                                 MessageBox.Show("錯誤次數過多,請三小時后再登錄");
74                                 return;
75                             }
76                             string dbpassword = reader.GetString(reader.GetOrdinal("Password"));
77                             if (dbpassword == textBox2.Text)
78                             {
79                                 ResetsErrorTime();
80                                 MessageBox.Show("登錄成功!");
81                             }
82                             else
83                             {
84                                 //在同一個連接中,如果SqlDataReader沒有關閉,那么是不能執行Update之類的語句的,
85                                 //因此,Update語句要放在其它函數內。  
86                                 IntsErrorTime();//調用此方法即可  
87                                 MessageBox.Show("登錄失敗!");
88                             }
89                         }
90                         else
91                         {
92                             MessageBox.Show("用戶名不存在!");
93                         }
94                     }
95                 }
96             }
97         }
98     }
99 }

 

9、導入導出數據案例

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using System.IO;
10 using System.Data.SqlClient;
11 
12 namespace myAdoNet02
13 {
14     public partial class Form2 : Form
15     {
16         public Form2()
17         {
18             InitializeComponent();
19         }
20 
21         private void button1_Click(object sender, EventArgs e)
22         {
23             //單純從button中的name屬性objImport得到ShowDialog()方法是不科學的
24             //
25             OpenFileDialog objImport = new OpenFileDialog();
26             if (objImport.ShowDialog() != DialogResult.OK)
27             {
28                 return;
29             }
30             using (FileStream filestream = File.OpenRead(objImport.FileName))
31             {
32                 using (StreamReader streamreader = new StreamReader(filestream))
33                 {
34                     using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;  
35             Integrated Security=True;Connect Timeout=30;User Instance=True"))
36                     {
37                         //創建連接是很耗時的,所以不能每插入一條數據就創建一次連接
38                         conn.Open();
39                         using (SqlCommand cmd = conn.CreateCommand())
40                         {
41                             cmd.CommandText = "insert into T_UserInfo(sUser,sPassWord) values(@sUser,@sPassWord)";
42                             string line = null;
43                             while ((line = streamreader.ReadLine()) != null)
44                             {
45                                 string[] str = line.Split('|');
46                                 string sUser = str[0];
47                                 string sPassWord = str[1];
48                                 cmd.Parameters.Clear(); 
49                                 //參數不能重復添加,在本while中用的是同一個SqlCommand對象,所以要在用完一次后,清除參數
50                                 cmd.Parameters.Add(new SqlParameter("sUser", sUser));
51                                 cmd.Parameters.Add(new SqlParameter("sPassWord", sPassWord));
52                                 cmd.ExecuteNonQuery();
53                             }
54                         }
55                     }
56                 }
57                 MessageBox.Show("導入成功");
58             }
59         }
60     }
61 }

 

10、手機號碼歸屬地查詢省市下拉列表實例

   (1、數據庫資源-全國省市數據庫 :http://www.programfan.com/blog/article.asp?id=28128

   (2、數據庫連接:大概有兩種形式

<add key="" value /?
<add name="" connectonstring="" /?
這兩方法對應的后台訪問方式不一樣的
第一種:System.Configuration.ConfigurationManager.AppSettings["myConn"]
第二種:ConfigurationManager.ConnectionStrings["myConn"].ConnectionString

   (3、要在類庫中找到ConfigurationManager.ConnectionStrings需要添加System.configuration

  (4、遇到一個問題,是這樣,因為同一個解決方案里我建立了多個項目,項目中基於數據庫服務文件名字起的差不多(我都是沒改名,自動生成的名字),所以導致后

面在生成調試的時候,總是遇到“數據庫未創建實例”這樣的錯誤。

 下面是手機號碼歸屬地查詢省市下拉列表實例:

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using System.Data.SqlClient;
10 using System.Configuration;
11 
12 namespace myAdoNet02
13 {
14     public partial class Form3 : Form
15     {
16         public Form3()
17         {
18             InitializeComponent();
19         }
20         //初始化
21 
22         private void Form3_Load(object sender, EventArgs e)
23         {
24             string myconStr = ConfigurationManager.ConnectionStrings["myConStr"].ConnectionString;
25 
26             using (SqlConnection conn = new SqlConnection(myconStr))
27             { 
28                 conn.Open();
29                 using (SqlCommand cmd = conn.CreateCommand()) {
30                     cmd.CommandText = "select * from promary";
31                     using (SqlDataReader reader = cmd.ExecuteReader()) {
32                         while (reader.Read()) {
33                             //構造model類
34                             Promary p = new Promary();
35                             //將數據庫中的數據賦值給model類中的屬性值
36                             p.ID = reader.GetInt32(reader.GetOrdinal("proID"));
37                             p.sName = reader.GetString(reader.GetOrdinal("proName"));
38                             Console.WriteLine(p.ID);
39                             Console.WriteLine(p.sName);
40                             Console.WriteLine(p);
41                             省.Items.Add(p);
42                         }
43                     }
44                 }
45             }
46         }
47         //選擇省后,查看市
48         private void 省_SelectedIndexChanged(object sender, EventArgs e)
49         {
50             市.Items.Clear();//清楚舊數據
51             Promary p2 = (Promary)省.SelectedItem;
52             int proID = p2.ID;
53 
54             string myConStr = ConfigurationManager.ConnectionStrings["myConStr"].ConnectionString;
55             using (SqlConnection conn = new SqlConnection(myConStr))
56             {
57                 conn.Open();
58                 using(SqlCommand cmd=conn.CreateCommand()){
59                     cmd.CommandText = "select * from city where proID=@ID";
60                     cmd.Parameters.Add(new SqlParameter("ID", proID));
61                     using (SqlDataReader reader = cmd.ExecuteReader()) {
62                         while (reader.Read()) {
63                             string sCityName = reader.GetString(reader.GetOrdinal("cityName"));
64                             市.Items.Add(sCityName);
65                         }
66                     }
67                 }
68            }
69         }
70 
71         class Promary
72         {
73             //下拉框的DisplayMember要設置為sName,才能顯示出來
74             public string sName { set; get; }
75             public int ID { set; get; }
76         }
77 
78     }
79 }

 

配置文件App.config

View Code
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3   <connectionStrings>
4     <add  name="myConStr"  connectionString="Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;  
5             Integrated Security=True;Connect Timeout=30;User Instance=True"/>
6   </connectionStrings>
7 </configuration>

 

11、手機號碼歸屬地查詢

 后台代碼:

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using System.Data.SqlClient;
10 using System.Configuration;
11 using System.IO;
12 
13 namespace 手機歸屬地導入查詢
14 {
15     public partial class Form1 : Form
16     {
17         public Form1()
18         {
19             InitializeComponent();
20         }
21 
22         private void button1_Click(object sender, EventArgs e)
23         {
24 
25             FolderBrowserDialog dlg = new FolderBrowserDialog();
26             if (dlg.ShowDialog() != DialogResult.OK)
27             {
28                 return;
29             }
30             string path = dlg.SelectedPath;
31             //清除數據
32             String connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
33             using (SqlConnection conn = new SqlConnection(connStr))
34             {
35                 conn.Open();
36                 using (SqlCommand cmd = conn.CreateCommand())
37                 {
38                     cmd.CommandText = "delete from T_PhoneInfo";
39                     cmd.ExecuteNonQuery();
40                 }
41             }
42 
43 
44             MessageBox.Show("11!");
45             string[] files = Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories);
46 
47             using (SqlConnection conn = new SqlConnection(connStr))
48             {
49                 conn.Open();
50                 using (SqlCommand cmd = conn.CreateCommand())
51                 {
52                     cmd.CommandText = "Insert into T_PhoneInfo(sEndNo,sName,sStartNo) values(@sEndNo,@sName,@sStartNo)";
53 
54                     foreach (string file in files)//遍歷文件名
55                     {
56                         string 運營商名稱 = Path.GetFileNameWithoutExtension(file);
57                         //不用StreamReader,因為文件很小,
58                         string[] lines = File.ReadAllLines(file, Encoding.Default);
59                         //一次性加載,也不占多少內存,ReadAllLines默認編碼是UTF-8
60 
61                         MessageBox.Show("22!");
62                         foreach (string line in lines)
63                         {
64                             string[] strs = line.Split('-');
65                             string 開始號碼 = strs[0];
66                             string 結束號碼 = strs[1];
67                             string 市 = strs[2];
68                             InsertExecuteNonQuery(結束號碼, 運營商名稱+市, 開始號碼);
69                         }
70                     }
71                 }
72             }
73             MessageBox.Show("導入成功!");
74         }
75 
76         public int InsertExecuteNonQuery(string sEndNo, string sName, string sStartNo)
77         {
78             string sqlString = "Insert into T_PhoneInfo(sEndNo,sName,sStartNo) values(@sEndNo,@sName,@sStartNo)";
79             String connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
80             
81             using (SqlConnection connetion = new SqlConnection(connStr))
82             {
83                 connetion.Open();
84                 using (SqlCommand Command = new SqlCommand(sqlString, connetion))
85                 {
86                     SqlParameter[] param = new SqlParameter[]
87                                 {
88                                       new SqlParameter("@sEndNo", sEndNo),
89                                       new SqlParameter("@sName", sName),
90                                       new SqlParameter("@sStartNo", sStartNo)
91  
92                                 };
93                     Command.Parameters.AddRange(param);
94                     return Command.ExecuteNonQuery();
95                 }
96             }
97         }
98     }
99 }

 

program.cs

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Windows.Forms;
 5 
 6 namespace 手機歸屬地導入查詢
 7 {
 8     static class Program
 9     {
10         /// <summary>
11         /// 應用程序的主入口點。
12         /// </summary>
13         [STAThread]
14         static void Main()
15         {
16             //(1)不要忘記把這段代碼放進來
17             //一定要放在最開始,否則提示成功也沒有導入到數據庫中
18             //(2)數據庫表設置主鍵
19             string dataDir = AppDomain.CurrentDomain.BaseDirectory;
20             MessageBox.Show(dataDir);
21             if (dataDir.EndsWith("\\bin\\Debug\\")
22                 || dataDir.EndsWith("\\bin\\Release\\"))
23             {
24                 //dataDir = System.IO.Directory.GetParent(dataDir).Parent.FullName;
25                 dataDir=dataDir.Replace("\\bin\\Debug\\", "");
26                 MessageBox.Show(dataDir);
27                 AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
28             }
29 
30             Application.EnableVisualStyles();
31             Application.SetCompatibleTextRenderingDefault(false);
32             Application.Run(new Form1());
33         }
34     }
35 }

 

配置文件:
   DataDirectory路徑無法讀取到,因為在DBbrowser里的mdf並不是debug中的mdf,所以改成絕對路就可以了

備注:如果配置文件不改為絕對路徑的話,需要改program.cs中

View Code
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3   <connectionStrings>
4     <add  name="ConnStr"  connectionString="Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\phone.mdf;  
5             Integrated Security=True;User Instance=True"/>
6   </connectionStrings>
7 </configuration>
8 <!--Connect Timeout=30;-->

 

12、DataSet的基本使用

  (1、封裝一個SQLHelper類:(用於被其它代碼調用,以下為該類的完整代碼)

***1、該類中含有四個方法,分別是:ExecuteNonQuery(string sql, params SqlParameter[] parameters)、ExecuteScalar(string sql, params

SqlParameter[] parameters)、ExecuteReader(string sql, params SqlParameter[] parameters)和ExecuteDataTable(string sql, params

SqlParameter[] parameters)。

在封裝這個類之前稱簡單介紹幾點:

a、封裝一個SQLHelper類方便使用,提供ExecuteNonQuery(string sql, params SqlParameter[] parameters);ExecuteScalar(string sql,

params SqlParameter[] parameters);ExecuteReader(string sql, params SqlParameter[] parameters);ExecuteDataTable(string sql,

params SqlParameter[] parameters)等方法,網上有微軟提供的最全的SQLHelper類,是Enterprise Library中的一部分。

b、用SQLHelper重寫登錄程序

c、new SqlParameter("e",0)的陷阱

d、sqlconnection在程序中一直保持它open可以嗎?對於數據庫來說,連接是非常寶貴的資源,一定要用完不close或dispose。

           ***2、ExecuteScalar 和ExecuteNonQuery的區別

           a、ExecuteScala 返回r結果集中第一行的第一列或空引用(如果結果集為空),返回的是一個object

           b、ExecuteNonQuery針對Connection 執行 SQL 語句並返回受影響的行數,返回的是一個int型值。

 SQLHelp.cs

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Data.SqlClient;
 6 using System.Configuration;
 7 using System.Data;
 8 
 9 namespace 封裝
10 {
11     class SQLHelp
12     {
13         public static readonly string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
14         /*優點:1、把數據庫連接代碼都放在SQLHelper中,使代碼更簡潔
15              *   2、使用DataTable可以隨意讀取數據庫,而之前做的用戶登錄使用的SqlReader只能逐行往前讀*/
16         
17          public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters)
18         {
19             using (SqlConnection conn = new SqlConnection(connStr))
20             {
21                 conn.Open();
22                 using (SqlCommand cmd = conn.CreateCommand())
23                 {
24                     cmd.CommandText = sql;
25                     foreach (SqlParameter parameter in parameters)
26                     {
27                         cmd.Parameters.Add(parameter);
28                     }
29                     return cmd.ExecuteNonQuery();
30                 }
31             }
32         }
33    
34          public static object ExecuteScalar(string sql, params SqlParameter[] parameters)
35          {
36              string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
37              using (SqlConnection conn = new SqlConnection(connStr))
38              {
39                  conn.Open();
40                  using (SqlCommand cmd = conn.CreateCommand())
41                  {
42                      cmd.CommandText = sql;
43                      foreach (SqlParameter parameter in parameters)
44                      {
45                          cmd.Parameters.Add(parameter);
46                      }
47                      //執行查詢,並返回查詢所返回的結果集中第一行的第一列。忽略其它的行或列。
48                      return cmd.ExecuteScalar();
49                  }
50              }
51          }
52          public static SqlDataReader ExecuteReader(string sql, params SqlParameter[] parameters)
53          {
54              string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
55              using (SqlConnection conn = new SqlConnection(connStr))
56              {
57                  conn.Open();
58                  using (SqlCommand cmd = conn.CreateCommand())
59                  {
60                      cmd.CommandText = sql;
61                     foreach (SqlParameter parameter in parameters)
62                      {
63                          cmd.Parameters.Add(parameter);
64                    }
65                      return cmd.ExecuteReader();
66                  }
67              }
68          }
69          public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
70          {
71              string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
72              using (SqlConnection conn = new SqlConnection(connStr))
73              {
74                  conn.Open();
75                 using (SqlCommand cmd = conn.CreateCommand())
76                  {
77                      cmd.CommandText = sql;
78                      foreach (SqlParameter parameter in parameters)
79                      {
80                          cmd.Parameters.Add(parameter);
81                      }
82                      //執行查詢,並返回查詢所返回的結果集中第一行的第一列。忽略其它的行或列。
83                      DataSet dataset = new DataSet();
84                      SqlDataAdapter adapter = new SqlDataAdapter(cmd);
85                      adapter.Fill(dataset);
86                      return dataset.Tables[0];
87                  }
88             }
89          }
90     }
91 }

 

Form1.cs

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using System.Configuration;
10 using System.Data.SqlClient;
11 using System.IO;
12 using 封裝.DataSet1TableAdapters;
13 
14 namespace 封裝
15 {
16     public partial class Form1 : Form
17     {
18         public Form1()
19         {
20             InitializeComponent();
21         }
22 
23         private void button1_Click(object sender, EventArgs e)
24         {
25             //ExecuteNonQuery 插入數據
26             SQLHelp.ExecuteNonQuery("insert into T_PhoneInfo(sStartNo,sEndNo,sName) values(@sStartNo,@sEndNo,@sName)", new SqlParameter("sStartNo", "11"), new SqlParameter("sEndNo", "11"), new SqlParameter("sName", "gaug懂"));
27             MessageBox.Show("插入數據成功");
28         }
29 
30         private void button2_Click(object sender, EventArgs e)
31         {
32             //ExecuteScalar 查詢條數
33             object i = SQLHelp.ExecuteScalar("select count(*)from T_PhoneInfo");
34             MessageBox.Show(Convert.ToString(i));
35         }
36 
37         private void button3_Click(object sender, EventArgs e)
38         {
39             //SqlDataReader 
40             SqlDataReader reader = SQLHelp.ExecuteReader("select * from T_PhoneInfo");
41             while (reader.Read())
42             {
43                 //運行到這里報錯,因為跟數據庫的連接已關閉,利用DataSet可以解決這類問題
44                 string sName = reader.GetString(reader.GetOrdinal("sName"));
45             }
46         }
47 
48         private void button4_Click(object sender, EventArgs e)
49         {
50             //注意只有在小數據量的時候才往DataSet里放,
51             //因為DataSet要占內存,大數據量的時候還是要用DataReader
52             string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
53             //定義一個DataSet
54             DataSet dataset = new DataSet();
55             //數據庫操作表
56             using (SqlConnection con = new SqlConnection(connStr))
57             {
58                 con.Open();
59                 using (SqlCommand cmd = con.CreateCommand())
60                 {
61                     cmd.CommandText = "select * from T_PhoneInfo";
62                     SqlDataAdapter adapter = new SqlDataAdapter(cmd); //執行select語句(要把cmd傳進去)
63                     adapter.Fill(dataset);//將執行結果得到的數據填充到dataset中
64                 }
65             }
66             //數據庫操作列
67             ///取dataset的表中的第0條數據
68             DataTable table = dataset.Tables[0];
69             for (int i = 0; i < table.Rows.Count; i++)
70             {
71                 DataRow row = table.Rows[i];
72                 string sName = Convert.ToString(row["sName"]);
73                 MessageBox.Show(sName);
74             }
75         }
76 
77         private void button5_Click(object sender, EventArgs e)
78         {
79             DataTable table = SQLHelp.ExecuteDataTable("select * from T_PhoneInfo");
80             for (int i = 0; i < table.Rows.Count; i++)
81             {
82                 DataRow row = table.Rows[i];
83                 string sName = Convert.ToString(row["sName"]);
84                 MessageBox.Show(sName);
85             }
86         }
87        
88 
89 
90     }
91 }

 

     (2、利用上述SQLHelper.cs類中的ExecuteDataTable(string sql, params SqlParameter[] parameters)方法,做一個登陸界面

 Form1.cs

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using System.Configuration;
10 using System.Data.SqlClient;
11 using System.IO;
12 using 封裝.DataSet1TableAdapters;
13 
14 namespace 封裝
15 {
16     public partial class Form1 : Form
17     {
18         public Form1()
19         {
20             InitializeComponent();
21         }
22 
23         private void button9_Click(object sender, EventArgs e)
24         {
25             //登陸
26             DataTable table = SQLHelp.ExecuteDataTable("select * from T_UserInfo where sUser=@sUser", new SqlParameter("sUser", txtUser.Text));
27             if (table.Rows.Count <= 0)
28             {
29                 MessageBox.Show("用戶名不存在");
30             }
31             else
32             {
33                 //用戶名存在,已經知道是哪一列了,要返回的行是從零開始的索引
34                 DataRow row = table.Rows[0];
35                 int sErroTime = Convert.ToInt32(row["sErroTime"]);
36                 if (sErroTime > 3)
37                 {
38                     MessageBox.Show("登陸次數過多");
39                     return;
40                 }
41                 string sPassWord = Convert.ToString(row["sPassWord"]);
42                 if (sPassWord == txtPassWord.Text)
43                 {
44                     SQLHelp.ExecuteNonQuery("update T_UserInfo set sErroTime=0 where sUser=@sUser", new SqlParameter("sUser", txtUser.Text));
45                     MessageBox.Show("登陸成功");
46                 }
47                 else
48                 {
49                     SQLHelp.ExecuteNonQuery("update T_UserInfo set sErroTime=sErroTime+1 where sUser=@sUser", new SqlParameter("sUser", txtUser.Text));
50                     MessageBox.Show("密碼錯誤!");
51                 }
52 
53             }
54         }
55 
56     }
57 }

 

   (3、

           **修改DataSet單擊事件如下:

a、可以更新行row["Name"]="sUser"、刪除行datatable.Rows.Remove()、新增行datatable.NewRow()。這一切都是修改的內存中的DataSet,並沒

有修改數據庫。

b、可以調用SqlDataAdapter的Update方法將對DataSet的修改提交到數據庫,Update方法有很多重載方法,可以提交整個DataSet、DataTable

或者若干DataRow。但是需要為SqlDataAdapter提供DeleteCommand、UpdateCommand、InsertCommand它才知道如何將對DataSet的修改提交

到數據庫,由於這幾個Command要求的格式非常苛刻,因此開發人員自己寫非常困難;可以用SqlCommandBuilder自動生成這幾個Command,

SqlCommandBuilder要求表必須有主鍵

c、通過DataRow的RowState可以獲得行的狀態(刪除、修改、新增等);調用DataSet的GetChanges()方法得到變化的結果集,降低傳遞的資源

           **測試強類型DataSet單擊事件

                敲寫代碼前,還要添加一個數據集DataSet1.xsd文件,然后打開數據集,將表拖到數據集中:

View Code
 1 private void button6_Click(object sender, EventArgs e)
 2         {
 3             //陷阱
 4             //實參為0與不為0時,這兩種情況下將光標放在SqlParameter中按F12轉到定義就出現不同的重載函數的情況,
 5             //非常詭異類型轉換陷阱!
 6             SQLHelp.ExecuteDataTable("select * from T_Users where Id=@Id", new SqlParameter("Id", (object)0));
 7             //修改方法是在0前加上object
 8         }
 9 
10         
11 
12         private void button7_Click(object sender, EventArgs e)
13         {
14             //修改DataSet
15             DataSet dataset = new DataSet();
16             string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
17             using (SqlConnection conn = new SqlConnection(connStr))
18             {
19                 conn.Open();
20                 using (SqlCommand cmd = conn.CreateCommand())
21                 {
22                     cmd.CommandText = "select * from T_UserInfo";
23                     SqlDataAdapter adapter = new SqlDataAdapter(cmd);
24                     adapter.Fill(dataset);
25 
26                     //修改Dataset中的數據
27                     DataTable talbe = dataset.Tables[0];
28                     DataRow row = talbe.Rows[0];
29                     row["sUser"] = "lcy";
30 
31                     talbe.Rows.RemoveAt(1);//刪除一行
32                     DataRow otherRow = talbe.NewRow();//新加一行
33                     //自動生成更新語句
34                     SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
35                     //更新DataSet,同步DataSet中的數據到數據庫
36                     adapter.Update(dataset);
37                 }
38                 //對於不返回任何鍵列信息的 SelectCommand,不支持 UpdateCommand 的動態 SQL 生成。
39                 //解決方案:表要設置主鍵
40             }
41 
42         }
43 
44         private void button8_Click(object sender, EventArgs e)
45         {
46             //測試強類型DataSet
47             T_UserInfoTableAdapter adapter = new T_UserInfoTableAdapter();
48             封裝.DataSet1.T_UserInfoDataTable data = adapter.GetData(); //獲取數據
49 
50             for (int i = 0; i < data.Count; i++)
51             {
52                 封裝.DataSet1.T_UserInfoRow userRow = data[i];
53                 MessageBox.Show(userRow.sUser);
54             }
55         }

 (4 、可空數據類型

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace 可空數據類型
 7 {
 8    class Program
 9     {
10         static void Main(string[] args)
11         {
12             string s1 = null;
13             //int i1=null;
14             int? i2 = 0;
15             int? i3 = null;//int? →可空的int,解決數據庫和C#對於int是否可以為null的不同所設置的
16             if (i3 == null)
17             {
18                 Console.WriteLine("i3為空");
19             }
20             else
21             {
22                 i3++;
23                 int i4 = (int)i3; //將可空的數據賦給不可空的,會報錯,加(int)i3以保證i3一定不為空
24                 Console.WriteLine("i3不為空,i3++={0}", i3);
25             }
26             if (i3.HasValue)
27             {
28                 int i4 = i3.Value;
29                 Console.WriteLine("i3不為空");
30             }
31             else
32             {
33                Console.WriteLine("i3為空");
34             }
35             int i6 = 10;
36             int? i5 = i6; //將不可空的賦給可空的,不會報錯
37         }
38     }

 (5、強類型DataSet判斷數據庫字段是否為null,強類型DataSet登陸,數據庫連接的連續性

View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using 封裝.DataSet1TableAdapters;
 10 using System.Diagnostics;
 11 
 12 namespace 封裝
 13 {
 14     public partial class Form2 : Form
 15     {
 16         public Form2()
 17         {
 18             InitializeComponent();
 19         }
 20 
 21         private void button1_Click(object sender, EventArgs e)
 22         {
 23             //判斷數據庫字段是否為空
 24             T_UserInfoTableAdapter adapter = new T_UserInfoTableAdapter();
 25             封裝.DataSet1.T_UserInfoDataTable table = adapter.GetData();
 26             封裝.DataSet1.T_UserInfoRow row = table[1];
 27 
 28             if (row.IssPassWordNull())
 29             {
 30                 table[1].sPassWord = "888888";
 31                 adapter.Update(table);
 32                 MessageBox.Show("密碼為空,已重置密碼");
 33             }
 34             else {
 35                 MessageBox.Show("密碼為:"+table[0].sPassWord);
 36             }
 37 
 38         }
 39 
 40         private void button2_Click(object sender, EventArgs e)
 41         {
 42             //DataSet 密碼登陸
 43             T_UserInfoTableAdapter adapter = new T_UserInfoTableAdapter();
 44             封裝.DataSet1.T_UserInfoDataTable table = adapter.GetDataByUser(txtUser.Text);
 45 
 46             if (table.Count <= 0)
 47             {
 48                 MessageBox.Show("用戶不存在");
 49             }
 50             else {
 51                 封裝.DataSet1.T_UserInfoRow row = table[0];
 52                 if (row.sErroTime > 3)
 53                 {
 54                     MessageBox.Show("登陸次數過多");
 55                     return;
 56                 }
 57                 else {
 58                     if (row.sPassWord == txtPassWord.Text)
 59                     {
 60                         adapter.UpdateErrorTimeBack(row.sUser);
 61                         MessageBox.Show("登陸成功");
 62                     }
 63                     else {
 64                         adapter.UpdateErrorTimeAdd(row.sUser);
 65                         MessageBox.Show("登陸失敗,密碼錯誤");
 66                     }
 67                 }
 68             }
 69 
 70         }
 71 
 72         private void button3_Click(object sender, EventArgs e)
 73         {
 74 
 75             Stopwatch gameTime = new Stopwatch();
 76             gameTime.Start();
 77             T_UserInfoTableAdapter adapter = new T_UserInfoTableAdapter();
 78 
 79             /*慢方法:數據連接是間斷的
 80                 for (int i = 0; i < 3000; i++)
 81                 {
 82                     adapter.Insert(i.ToString(),i.ToString(),0);
 83                 }*/
 84 
 85             /*快方法:數據連接是連續的*/
 86             adapter.Connection.Open();
 87             for (int i = 0; i < 3000; i++)
 88             {
 89                 //先刪除上個例子的數據  adapter.Delete(i.ToString(), i.ToString(), 0);
 90                 adapter.Insert(i.ToString(), i.ToString(), 0);
 91             }
 92             adapter.Connection.Close();
 93 
 94             gameTime.Stop();
 95 
 96             MessageBox.Show(gameTime.Elapsed.ToString());
 97         }
 98 
 99     }
100 }

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM