ADO.NET实例教学二

ADO.NET实例教学二

在上一篇文章ADO.NET实例教学一的实例当中,资料管理器的功能没有完全的实现,下面我们继承上一篇文章的内容把这个案例说完。

首先要完成:为某个类别下导入数据功能(文件夹下的文本文件)。

具体解释,选择一个子类别,单击鼠标右键导入,选择文件路径,选择个文件夹,把文件夹下的所有的文本文件导入数据库。

文章标题就是文本标题,文章内容就是文本里面的内容。

                       

一、理清功能对应的表中信息

思路1.增加右键菜单 - 点击treeview节点时显示右键菜单 - 一点右键菜单弹出选择路径的对话框 - 选择路径 - 搜索文本文件 - 读取文本内容 – 插入文本内容,文件名。

右键菜单不会用的话,可以在菜单栏添加一个按钮,一点按钮弹出一个对话框路径。

 

第二个任务是:在选中的子列别下增加一篇文章

具体解释:选中子列别,一点按钮,弹出一个对话框,对话框要求输入标题和内容,插入。

 

二、任务2用到的功能

向笑话百科里面插入一篇文章,选中列别,点击菜单选项,弹出对话框,输入内容,插入表中,标题,内容分别插入表中。

这个功能就是执行一条sql语句。

 

任务3:在选中父类别下增加一个子类别

 

任务4:类别的导出,导出到记事本。

具体解释:把当前类别中的文章导出到一个文件夹下,这个文件夹下包含多个记事本。

上面的这四个任务有兴趣的朋友您可以先做下,后面我给出答案。

 

下面我们说下:DataSet(ado.net断开式数据访问)不是重点内容

什么是DataSet呢?当它把数据从数据库中取出来后,就完全跟数据库断开连接了。可以把它当成数据库来用,一个数据库可以包含多张表,一个DataSet里面也可以包含多张表。DataSet好比是数据库,里面的表就好比是datatable。

接下来演示下DataSet怎么用?

顺便介绍下DataGridView这个控件。这个控件可以把我们查询的数据用一个窗体显示出来。

 

三、DataGridView的使用

点击按钮,把学生表中的数据显示到DataGridView上面。

用DataSet方式呦。

 

四、DataSet的使用

             

五、另外一种写法

接着咱们循环遍历dataset中的每一行到控制台.

 

六、输出过程

 

七、循环输出到控制台的代码

 

八、调试中的技巧

现在我们再说下怎么创建一个DataSet。从头到尾创建一个空的DataSet,自己创建列,自己给它创建行。自己输出。

 

九、研究下为什么不能这么写

 

十、手动创建DataSet

 下面我们讲解下:通过数据源绑定的方式使用ComboBox。

                       

十一、题目

 

十二、过数据源绑定的方式使用ComboBox代码

ValueMember是选中的id,DisplayMember是显示的内容。这里也应该using一下。

大家思考一下,只有DataTable能作为数据源么?list集合可以么?什么样的类型能作为数据源进行绑定呢?数组能绑定过来么?

 

十三、数组也能够绑定进来

 

十四、什么都能绑么?

 

十五、真的什么都能绑么?

 

十六、查看MSDN

 

十七、DataGridView的数据源

不同的控件到底能绑定什么数据源就看实现哪个接口就可以了。大家以后可以也试着查一下帮助。

以后我们执行增,删,查,改就调这个方法就可以了,这个类叫做SqlHelper.下面我们就介绍SqlHelper.

我们在写之前总结一下我们之前对数据库进行操作无非就是:

执行insert\delete\update→ExecuteNonQuery()

执行count(*)等返回单个值的→ExecuteScalar();

执行大量查询,→ExecuteReader();

执行返回DataTable或DataSet

接下来我们就写个类,类的名字叫SqlHelper,这个类里面就包括执行这四种操作的方法。

 

十八、从配置文件开始

 

十九、写好的连接字符串

写好的配置文件插入位置:

View Code
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3   <connectionStrings>
4     <add name="sql" connectionString="Data Source=HY-PC;Initial Catalog=itcastcn;Integrated Security=True"/>
5   </connectionStrings>
6 </configuration>

二十、封装ExecuteNonQuery方法

 

二十一、错误代码

 

二十二、这样写还是有问题

 

二十三、封装DataReader最终代码

SqlHelper代码插入位置:

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 _08自己封装一个SqlHelper
10 {
11     public static class SqlHelper
12     {
13         //2.把连接字符串放在外面
14         private static readonly string constr = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
15         #region 执行insert、delete、update的方法ExecuteNonQuery
16         //1.有返回值int类型,有参数:sql,可变参数params
17         public static int ExecuteNonQuery(string sql, params SqlParameter[] pms)
18         {
19             using (SqlConnection con = new SqlConnection(constr))
20             {
21                 using (SqlCommand cmd = new SqlCommand(sql, con))
22                 {
23                     if (pms != null)//???
24                     {
25                         cmd.Parameters.AddRange(pms);
26                     }
27                     con.Open();
28                     return cmd.ExecuteNonQuery();
29                 }
30             }
31         }
32         #endregion
33 
34         #region 执行返回单个值的方法
35         public static object ExecuteScalar(string sql, params SqlParameter[] pms)
36         {
37             using (SqlConnection con = new SqlConnection(constr))
38             {
39                 using (SqlCommand cmd = new SqlCommand(sql, con))
40                 {
41                     if (pms != null)
42                     {
43                         cmd.Parameters.AddRange(pms);
44                     }
45                     con.Open();
46                     return cmd.ExecuteScalar();
47                 }
48             }
49         }
50         #endregion
51 
52         #region 执行返回DataTable
53         public static DataTable ExecuteDataTable(string sql, params SqlParameter[] pms)
54         {
55             DataTable dt = new DataTable();
56             using (SqlDataAdapter adapter = new SqlDataAdapter(sql, constr))
57             {
58                 //虽然看不到Command对象,但是在内部adapter内部创建了Command对象。在SelectCommand里面。
59                 if (pms != null)
60                 {
61                     adapter.SelectCommand.Parameters.AddRange(pms);
62                 }
63                 adapter.Fill(dt);
64                 return dt;
65             }
66         }
67 
68         #endregion
69 
70         #region 执行返回DataReader
71         public static SqlDataReader ExecuteDataReader(string sql, params SqlParameter[] pms)
72         {
73             //在写reader时,我们一般会try-catch起来
74             SqlConnection con = new SqlConnection(constr);
75             using (SqlCommand cmd = new SqlCommand(sql, con))
76             {
77                 if (pms != null)
78                 {
79                     cmd.Parameters.AddRange(pms);
80                 }
81                 try
82                 {
83                     con.Open();
84                     //CommandBehavior.CloseConnection这个参数表示,当用户使用完毕DataReader后,当关闭DataReader时,自动关闭与其关联的Connection
85                     return cmd.ExecuteReader(CommandBehavior.CloseConnection);
86                 }
87                 catch
88                 {
89                     con.Close();
90                     con.Dispose();
91                     throw;
92                 }
93             }
94 
95         }
96         #endregion
97     }
98 }

 下面我们先复习下上面讲解的SqlHelper

由于我们已经学习了配置文件,带参数的sql语句以及SqlHelper,我们就用这些来完成我们下面的工作.

                       

二十四、添加配置文件

 

二十五、选择-应用程序配置文件

 

二十六、写配置文件需要注意的地方

下面我们先建个SqlHelper。

 

二十七、添加SqlHelper类

 

二十八、写类和字符串

 

二十九、sql对应配置文件中键的名称

接下来我们就开始封装那几个常用的方法,

 

三十、写方法和做判断需要注意的地方

 

三十一、object类型

 

三十二、封装DataTable方法需要注意的地方

 

三十三、封装SqlDataReader方法需要注意的地方

好了,封装方法需要注意的地方我们又非常详细的说了一遍,下面我们就用下我们封装好的SqlHelper类。

 

三十四、下面我们就对这张表进行一些基本的操作

 

三十五、画好界面

当点击按钮:添加,添加信息。

 

三十六、结果演示

 

三十七、调用SqlHelper执行插入代码

                     实现让用户输入班级Id,点击按钮:删除。进行删除操作。

         

三十八、画好界面

 

三十九、傻逼班长那行没有了

 

四十、删除班级记录代码

更新的时候需要注意一下,更新,就是编辑,先把原纪录读取出来。那么,不读取原纪录,直接更新行不行?

 

四十一、看这个功能的实现

这个功能的Sql语句该怎么去写呢?

 

四十二、更新后结果

 

四十三、更新的代码

最后我们来看看查询。我们现用DataReader做一下,再用DataTable来演示一下。

 

四十四、输出结果

 

四十五、表中的数据都输出出来了

 

四十六、DataReader查询功能代码

接下来我们看下这个需求:点击按钮显示TblClass表中记录的条数

要想获取这个记录条数,执行什么样的Sql语句呢?

 

四十七、查询条数的演示图

 

四十八、查询返回条数的代码

                   

四十九、查询所有数据直接绑定到DataGridView上面

 

五十、通过DataTable绑定数据的效果

 

五十一、通过DataTable绑定数据代码

 

五十二、设个断点调试一下

 

五十三、为什么要加null判断

下面我们再把数据库中插入空值问题说下:

 

五十四、做好准备工作

 

五十五、插入代码初步写法

 

五十六、不输入表示是个空字符串

 

五十七、加上判断以后报错了

 

五十八、解决第二个报错

 

五十九、成功插入null

插入空值的代码:

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using _9._7复习内容;
 6 using System.Data.SqlClient;
 7 
 8 namespace _02通过带参数的sql语句向数据库中插入空值问题
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             //1.提示用户输入班级名称,描述
15             Console.WriteLine("请输入班级名称:");
16             string clsName = Console.ReadLine();
17             Console.WriteLine("请输入班级描述:");
18             string clsDesc = Console.ReadLine();     
19             //5.这样去判断
20             if (clsDesc.Length==0)
21             {
22                 clsDesc = null; //C#中的空值,无法直接应用于数据库,需要用数据库中的空值 ,数据库中的空值DBNull.Value
23             }
24             //3.声明sql语句
25             string sql = "insert into TblClass(tClassName,tClassDesc) values(@tname,@tdesc)";
26             //4.增加两个参数
27             SqlParameter[] pms = new SqlParameter[] { 
28             new SqlParameter("@tname",clsName),
29             new SqlParameter("@tdesc",clsDesc==null?DBNull.Value:(object)clsDesc)
30             };
31             //2.调SqlHelper
32             int r=SqlHelper.ExecuteNonQuery(sql,pms);
33             Console.WriteLine("成功插入{0}行。",r);
34             Console.ReadKey();  
35         }
36     }
37 }

下面我们再把资料管理器说一遍:

 

六十、做好准备

 

六十一、需要用到的两张表

 

六十二、画好界面

 

六十三、界面上需要用到的一些属性

 

六十四、加载效果

加载类别代码位置:

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 _9._7复习内容;
11 
12 namespace _03资料管理器
13 {
14     public partial class Form1 : Form
15     {
16         public Form1()
17         {
18             InitializeComponent();
19         }
20         /// <summary>
21         /// 窗体加载事件
22         /// </summary>
23         /// <param name="sender"></param>
24         /// <param name="e"></param>
25         private void Form1_Load(object sender, EventArgs e)
26         {
27             //1.获取子类别
28             DataTable dt = GetCategoryByPid(-1);
29             LoadCategory(treeView1.Nodes,dt);
30         }
31 
32         private void LoadCategory(TreeNodeCollection treeNodeCollection, DataTable dt)
33         {
34             //2.把dt中的数据绑定到treeNodeCollection中
35             foreach (DataRow dr in dt.Rows)
36             {
37                 TreeNode node=treeNodeCollection.Add(dr[1].ToString());
38                 node.Tag = dr[0];
39                 //4.根据id写个dt
40                 DataTable dtSub=GetCategoryByPid(Convert.ToInt32(dr[0]));
41                 //3.再绑下,因为根节点下面还有子节点
42                 LoadCategory(node.Nodes,dtSub);
43             }
44         }
45         //写个方法根据父ID获取类别,我们这次用DataTable存放类别。
46          /// <summary>
47          /// 根据父Id获取所有的子类别
48          /// </summary>
49          /// <param name="pid"></param>
50          /// <returns></returns>
51         private DataTable GetCategoryByPid(int pid)
52         {
53             string sql = "select tid,tname from Category where tParentId=@pid";
54             SqlParameter[] pms = new SqlParameter[] { 
55             new SqlParameter("@pid",pid)
56             };
57             DataTable dt=SqlHelper.ExecuteDataTable(sql, pms);
58             return dt;
59         }
60     }
61 }

记载标题,显示文章上次做过我们就不做了。

下面做下在选中的类别下面,通过文件夹导入文本。

 

六十五、画好马上要做的三个功能的界面

接下来,点击第三个分类的时候,要弹出个选择文件夹的对话框。

 

六十六、文件夹控件

 

六十七、参数放在外面报错

导入文本文件代码:

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 _9._7复习内容;
 11 using System.IO;
 12 
 13 namespace _03资料管理器
 14 {
 15     public partial class Form1 : Form
 16     {
 17         public Form1()
 18         {
 19             InitializeComponent();
 20         }
 21         /// <summary>
 22         /// 窗体加载事件
 23         /// </summary>
 24         /// <param name="sender"></param>
 25         /// <param name="e"></param>
 26         private void Form1_Load(object sender, EventArgs e)
 27         {
 28             //1.获取子类别
 29             DataTable dt = GetCategoryByPid(-1);
 30             LoadCategory(treeView1.Nodes,dt);
 31         }
 32 
 33         private void LoadCategory(TreeNodeCollection treeNodeCollection, DataTable dt)
 34         {
 35             //2.把dt中的数据绑定到treeNodeCollection中
 36             foreach (DataRow dr in dt.Rows)
 37             {
 38                 TreeNode node=treeNodeCollection.Add(dr[1].ToString());
 39                 node.Tag = dr[0];
 40                 //4.根据id写个dt
 41                 DataTable dtSub=GetCategoryByPid(Convert.ToInt32(dr[0]));
 42                 //3.再绑下,因为根节点下面还有子节点
 43                 LoadCategory(node.Nodes,dtSub);
 44             }
 45         }
 46         //写个方法根据父ID获取类别,我们这次用DataTable存放类别。
 47          /// <summary>
 48          /// 根据父Id获取所有的子类别
 49          /// </summary>
 50          /// <param name="pid"></param>
 51          /// <returns></returns>
 52         private DataTable GetCategoryByPid(int pid)
 53         {
 54             string sql = "select tid,tname from Category where tParentId=@pid";
 55             SqlParameter[] pms = new SqlParameter[] { 
 56             new SqlParameter("@pid",pid)
 57             };
 58             DataTable dt=SqlHelper.ExecuteDataTable(sql, pms);
 59             return dt;
 60         }
 61 
 62         private void 将指定ToolStripMenuItem_Click(object sender, EventArgs e)
 63         {
 64             //1.点它弹出文件夹对话框,接收下枚举,看看它打开的状态是什么。
 65             DialogResult result=folderBrowserDialog1.ShowDialog();
 66             if (result==DialogResult.OK)
 67             {
 68                 //2.获取用户选择的文件夹路径
 69                 string path = folderBrowserDialog1.SelectedPath;
 70                 //3.搜索路径下所有的文本文件,也可以搜索下所有子文本文件
 71                 string[] txts = Directory.GetFiles(path, "*.txt",SearchOption.AllDirectories);
 72                 //4.循环获取每个文本文件的文件名与文件的具体内容
 73 
 74                 ////这里不能把同一个SqlParameter参数添加到多个SqlCommand中。
 75                 ////5.每次循环的时候,都要创建这么几个参数,不爽。把参数提到外面。
 76                 //SqlParameter[] pms = new SqlParameter[]{
 77                 ////当前选中的节点的tag就是类别id
 78                 //new SqlParameter("@tid",SqlDbType.Int),
 79                 //new SqlParameter("@title",SqlDbType.VarChar),
 80                 //new SqlParameter("@content",SqlDbType.VarChar)
 81                 //};
 82                 foreach (string txtInfo in txts)
 83                 {
 84                     //获取文件名
 85                     string title = Path.GetFileName(txtInfo);
 86                     //获取具体内容,处理下编码问题。
 87                     string content = File.ReadAllText(txtInfo,Encoding.Default);
 88                     //调用SqlHelper执行插入语句
 89 
 90                     string sql = "insert into ContentInfo(dtid,dname,dcontent) values(@tid,@title,@content)";
 91                     //5.把每次的值动态变一下。因为当大量创建对象的时候,本身也会消耗性能。
 92                     #region 1
 93                     //pms[0].Value = treeView1.SelectedNode.Tag;
 94                     //pms[1].Value = title;
 95                     //pms[2].Value = content;
 96                     #endregion
 97                     
 98                     #region 在循环里面创建参数
 99                     SqlParameter[] pms = new SqlParameter[]{
100                     //当前选中的节点的tag就是类别id
101                     new SqlParameter("@tid",treeView1.SelectedNode.Tag),
102                     new SqlParameter("@title",title),
103                     new SqlParameter("@content",content)
104                     };
105                     #endregion
106                     SqlHelper.ExecuteNonQuery(sql,pms);
107                 }
108                 MessageBox.Show("数据导入完毕!");
109             }            
110         }
111 
112        
113     }
114 }

接下来咱们再做下添加子类别。还是要判断当前是否有选中类别,选中类别是否是一级类别。

 

六十八、更新菜单,代码写作过程

 

六十九、增加子类别向子类别下增加文章演示

 

七十、留作大家的练习

建表的代码:

View Code
 1 use master
 2 if exists(select * from sysdatabases where [name] = 'PhoneNumManager')
 3     drop database PhoneNumManager
 4 go
 5 create database PhoneNumManager
 6 go
 7 use PhoneNumManager
 8 go
 9 create table PhoneType
10 (
11     ptId int identity(1,1) primary key,
12     ptName nvarchar(50) 
13 ) 
14 
15 go
16 create table PhoneNum
17 (
18     pId int identity(1,1) primary key,
19     pTypeId int not null,
20     pName nvarchar(50),
21     pCellPhone varchar(50),
22     pHomePhone varchar(50)
23 )
24 go
25 alter table PhoneNum
26 add constraint FK_PhoneNum foreign key (pTypeId) references PhoneType(ptId)
27 go
28 
29 create view view_Phone
30 as 
31     select pId, pTypeId, pName, pCellPhone, pHomePhone,ptName from dbo.PhoneNum
32     inner join dbo.PhoneType on pTypeId = ptId
33 go
34 
35 
36 insert into PhoneType values('朋友')
37 insert into PhoneType values('同事')
38 insert into PhoneType values('同学')
39 insert into PhoneType values('家人')
40 
41 
42 insert into PhoneNum values(1,'刘备','13000000000','7000000')
43 insert into PhoneNum values(1,'关羽','13000000001','7000001')
44 insert into PhoneNum values(1,'张飞','13000000002','7000002')
45 insert into PhoneNum values(2,'曹操','13300000003','8000003')
46 insert into PhoneNum values(2,'大乔','13300000004','8000004')
47 insert into PhoneNum values(3,'孙权','13400000003','9000003')
48 insert into PhoneNum values(3,'小乔','13400000004','9000004')

要求,加载分组列表。根据姓名或者号码like模糊查询。

窗体加载的时候默认把所有人得信息都加载起来。只需要显示分组的编号就可以了。

当选中某条数据的时候,下边显示详细信息。点保存,保存数据。点删除,删除数据。

点数据导出,把数据导出到csv文件,我们下篇文章马上要说下多条件搜索,敬请期待!!!

回到起始位置

元旦快乐,本博主祝大家每天都有好心情!吃好,玩好,喝好!!!

作者近期文章列表:

C#中级进阶教程(完全免费,献给代码爱好者的最好礼物。注:本作者分享自己精心整理的C#中级进阶教程,无任何商业目的。希望与更多的代码爱好者交流心得,也请高手多多指点!!!)
ASP.net项目 图书商城项目总论
三层及其它内容 递归
三层(一)
三层相关案例(及常见的错误)
三层实例(内涵Sql CRUD)
手写代码生成器
SQL数据库 ADO.net 数据库的应用图解一
数据库的应用详解二
ADO.NET(内涵效率问题)
ADO.NET实例教学一
ADO.NET(内含存储过程讲解)
面向过程,面向对象中高级 面向过程,面向对象的深入理解一
面向过程,面向对象的深入理解二
面向对象的深入理解三
无处不在的XML
winform基础 Winform基础
winform中常用的控件
面向过程 三种循环的比较
C#中的方法(上)
我们常见的数组
面向对象 思想的转变
C#中超级好用的类
C#中析构函数和命名空间的妙用
C#中超级好用的字符串
C#中如何快速处理字符串
值类型和引用类型及其它
ArrayList和HashTable妙用一
ArrayList和HashTable妙用二
文件管理File类
多态
C#中其它一些问题的小节
GDI+ 这些年我收集的GDI+代码
这些年我收集的GDI+代码2
HTML概述以及CSS 你不能忽视的HTML语言
你不能忽视的HTML语言2精编篇
你不能忽视的HTML语言3
html-综合篇
CSS基本相关内容--中秋特别奉献
CSS基本相关内容2
JavaScript基础 JavaScript基础一
javascript基础二JavaScript DOM编程
jQuery jQuery(内涵: jquery选择器)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值