欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ADO.NET- 基础总结及实例

程序员文章站 2022-09-02 22:42:49
1、ADO.NET基础介绍  (1、程序要和数据库交互要通过ADO.NET进行,通过ADO.NET就能在程序中执行SQL了。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方法执行一个非查询语句(Update、inset、Delete等)

     (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

          reader的GetString、GetInt32等方法只接受整数参数,也就是序号,用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在出了作用域以后调用Dispose,SqlConnection 、FileStream 等的Dispose内部都会做这样的判断:判断有没有close,如果没有,就

先Close再Dispose。

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表示“此处用参数代替”,向SqlCommand的Parameters中添加参数。

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、数据库资源-全国省市数据库     (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