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 }

 

 

 

 

 

 

 

 

 

 

 

posted @ 2013-04-17 23:54  daomul  阅读(3442)  评论(2编辑  收藏