ADO.net入门(四):SQL数据集
编辑:浏览器知识向数据库发送指令后,数据库就会把结果集当作回礼,这回礼就是我们想要的东东。
前面我们说了水管和消防车,水管就是“连接类”,就是一直和数据库相连接的,一次一行记录,向前只读的处理
消防车就是“非连接类”,就是断开式的结果集,把结果集获取后,立马断开,把这大块的结果拿到本地来处理。
水管就是DataReader
消防车就是DataAdapter
消防车只是一个转换的机器,把水厂的水转为消防车中的水,而消防车的不就是DataSet,这种水就是我们缺水用户用的。
因此正好上面标题所说,回礼没有装上口袋,它就是婆家的东西,只有装在口袋(消防车中的水箱)才是我们能“直接操作”的东西。
因为这个时候回礼就是我们自己的东西,自己的东西怎么处理都不为过,你想怎么操作就操作,你想扔了都行(千万别当着人前人,嘿嘿)
当然,你第二年你没钱买礼物,可以把上年回礼变化一下,加个工就成了新的东东(礼物),再次“还回给”娘家,也是可以的。这就相当
于把当前的礼物变个花样更新到原来的数据库中,使原来的数据库发生变化。
说了一大堆,只有两点
一、创建数据集,就是指令发送到数据库后,数据库会产生一个数据集。
二、填充数据集,就是数据库的数据集,被消防车填充到水箱DataSet中,我们实际用的就是这个DataSet。
注意:这两点只是针对“非连接类”。因为连接类太简单了。
啥?我还没理解连接类。那我们再看一下DataReader这个只读向前的。反正只先学简单的,我们就最基础最基础来学。
Imports System.Data.SqlClient
Module Module1
Sub Main()
Dim cn As New SqlConnection
cn.ConnectionString = "Password=123456;User ID=sa;Initial Catalog=学生成绩管理系统;Data Source=QZHENG"
cn.Open()
If cn.State = ConnectionState.Open Then
Console.WriteLine("连接已经成功!")
Console.WriteLine()
Dim cmd As New SqlCommand
cmd.CommandType = CommandType.Text
cmd.CommandText = "select * from 学生信息"
cmd.Connection = cn
Dim dr As SqlDataReader
dr = cmd.ExecuteReader() '发送指令并返回结果到dr,这样dr就是一个结果集对象
Console.WriteLine("下面可以看到读一次只能得到一行记录:")
dr.Read() '发送读取命令,返回的结果不是记录,是一个判断是否有记录的真值,有记录返回真true,否则为假falsh
'结果可以通过当前的dr.getstring(N) 或dr.getdatetime(N),或dr[字段名]来得到
Console.WriteLine("学号:{0} 姓名:{1} 出生日期:{2}", dr.GetString(0), dr.GetString(1), dr.GetDateTime(3))
'上面是一个输出格式,前面0,1,2处的字符分别用后面的0,1,3得到的结果来填充占位,后面的0,1,3分别对应表的字段顺序
'注意,最后一个是getdatetime因为这个字段的类型是datatime类型,而不是字串String类型的。
Console.WriteLine()
Console.WriteLine("可以看到上面读一次只能得到一个记录,所以下面用一个循环来一次性读完")
While (dr.Read())
'下面用另一种格式来输出
Console.WriteLine("学号:{0} 姓名:{1} 出生日期:{2}", dr("学号"), dr("姓名"), dr("出生日期"))
'可以看出,用字段名来指明,更不容易犯错。注意在VB2008中上面是用方括号的如dr["学号"]
'Console.WriteLine("学号:{0} 姓名:{1} 出生日期:{2}", dr(0), dr(1), dr(3))
'这个语句也可达到相同的目的,可惜没有人指点我,在看了N多书才发现输出格式的“秘密”
End While
End If
cn.Close()
Console.ReadKey()
End Sub
End Module
第一次只读了一次,所以只能得到一个结果
第二次用了一个循环,dr.read()的结果真假来判断是否有记录,只有到了最后一条的下面,它才会是假,即这样就把记录集读完了。
每读一次就把结果输出来。
上面两个关键点:
一、dr对象须由对象com.executeReader()方法得到关联到结果集,这样dr就有了“生命和内容“,这样dr才能dr.read()进行取数据。
二、输出的格式,三种方式,只有带了字段名的最为恰当,不易出错,别人又能读懂。
===================上面是一次读一行的“连接类”读取数据集的方法======================================================
下面接着说“非连接类”,,,就是断开式的结果集。
它分两步:一就创建结果集,二是填充成结果集,这里可理解成搬运到本地来。
本质上消防车就是搬运工,它把服务器的结果集,装成水箱中的结果集,搬运到应用程序去。
一、创建数据集
与SqlServer连接成功后,发出指令,数据库就会根据指令(SQl命令或存储过程)在服务器的内存里面创建一个原数据库的
“副本”(即数据集,学了SqlServer,这个又叫临时表)。
任何针对数据库的添加、删除和修改等操作都是先从内存中的数据库“副本”进行操作,然后 ,再把这个副本更新到数据库中,
这样大大提高了数据交互的效率。
上面是说的在服务器内部发生的情况,这些情况是根据应用程序发出指令后,服务器产生的动作。
再看一下水箱,我们主要操作的对象就是水箱(DataSet)
DataSet是Ado.ne结构的主要组件,也是最常见的数据集对象,我们操作的主要东西就是它,因为它能完成各种复杂的任务。
DataSet是一种容器,它由消防车DataAdapter来填充装满水(结果集)。因此它是不能直接与数据库(水厂)来打交道的,它
只能通过消防车DataAdapter与数据库打交道。为什么这样做呢?
这就是微软聪明的地方。因为现在互联网是分布式的,A处有A数据库存储的是人员名单,B处有B数据库存在的学历,
可以看到,人员名单与学历不在同一个数据库(服务器)上,即水厂不同,怎么办呢?不怕,专门有跑路的消防车,从A处
拉点水,再从B处拉一点与A有关系的水,这样消防车就可以和两个水厂打交道。
最终的结果,消防车中的水就是两个数据库的水的交集了,这样分工就明确了,DataAdapter只与数据库打交道,DataSet
只与最终的结果集打交道,我们只管DataSet,最后修改这个水箱的结果集后,消防车是如何把水再次原本原样地返回到上面
各自的两个厂水,我们不用管,DataAdapter自己会处理,它不跑路难道还要我们去跑路?!谁叫它干的就是“搬运工“的活呢?
所以,DataSet设计的目的就是独立于任何数据源(包括数据库,XML数据源)的数据访问。
DataSet可以将数据和架构作用xmL文档进行读写。数据和架构可以通过Http传输,并在支持XML的任何平台上被任何应用程序
使用。
可以用WriteXmlSchema方法将架构保存为Xml架构,并且可以使用WriteXml方法保存架构和数据
关于XMl又是一个大课题,反正它和非连接类关联着,嘿嘿
创建DataSet对象非常简单:
dim ds as new SqlDateSet()
当然创建了它,它还是一个空箱,没有水(结果集),怎么来填充,就是那个”搬运工“消防车的事了,它来填充。
二、填充数据集
空水箱,没有任何东西,应用程序也没办法去处理,于是消防车DataAdapter又发挥了吃苦耐劳的精神,不断地向里面填充一个
水厂或多个水厂的的水,只不过计算机、网络很快,我们基本上查常见不出时间差,不得不佩服消防车的效率高啊,赞一个!
对于SQlserver的搬运工就是sqlDataAdapter,可以看到前面名字就是针对Sql的。不要以为换了一个马甲加个SQl前缀,我们就不认识?!
前面加个SQl只不过是针对SqlServer数据库呗,下面一样理解,自动跳过Sql进行识别。
SqlDataAdapter表示一组数据命令和一个数据库连接,它是用来填充DataSet和更新数据源的(把水返回到水厂)
SqlDataAdapter的Fill()方法用于使用SqlDataAdapter的SelectionCommand(查询)的结果来填充DataSet的。可以看一第一节
中有四个命令,SelectCommand用于把水填充到水箱,InsertCommand用于应用程序把添加的记录返回到数据库,DeleteCommand
用于删除部分或全部记录,UpdateCommand用于对数据库的记录进行修改。
Fill()将要填充的DataSet和Datatable对象(或者要使用SelectCommand中返回的行来填充的DataTable的名称)作为参数,
(水箱是一个集合,它可以分格成几个小水箱,每个小水箱就是一个表集体DataTable)
使用DataReader对象隐匿地返回用于在DataSet中创建表的列名和类型以及用于填充DataSet中的表行的数据。这什么意思?
我们只用DataReader,就得一直保持连接,但是,如果用了消防车,就可以用DatarReader把水一点一点装满水箱,装满后
我们立马扔掉DataReader,哈哈,功利之名就是这样的,呼之及来,不用就弃之,这样DataSet就可以拉回来了,这时就可以
与数据库断开了,而水箱的水我们是可以操作的,达到断开数据库的目的,用完操作完后,搬运工再拉回去一点一点返回各自的
水厂或水池。
下面看一下填充的情况
Imports System.Data.SqlClient
Module Module1
Sub Main()
Dim cnString As String = " Password=123456;User ID=sa;Initial Catalog=学生成绩管理系统;Data Source=QZHENG"
Dim cn As New SqlConnection(cnString) '构造函数
cn.Open()
Dim Sql As String = "select * from 学生信息"
Dim cmd As New SqlCommand(Sql, cn)
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet
da.Fill(ds, "学生信息")
'这样ds水箱就被填充了,但这个结果集怎么一条一条的取出来来操作呢?这就是我们“复杂地操作它的”的目的。
cn.Close()
Console.ReadKey()
End Sub
End Module
上面用构造法逐个构造对象,先SQlconnection,然后SQlCommand对象,最后SqlDataAdapter对象来执行cmd查询,最后再用Fill()方法来填充查询结果保存到数据集DS中
用户可以将任意数据量的DataAdapter对象与DataSet一起使用,并且每个DataAdapter都 可以用于填充一个或者多个DataTable
对象并将更新解析回相关数据源。
小心下面的功能跨步
正如原来邮政局只能是寄东西的,结果,发展起来了副业,比如邮政储蓄,
各个对象一样,在专精本人的东西时,它也干点别人的东西,因为每个人都认真自己 是全才,所以都得会点什么的。
这不,SqlDataAdapter有时也耐不住寂莫,它也会“出格”干点本来是别人发送命令的一事来。
所以下面的代码就没有发送指令的东西,SQlCommand对很幽怨地说:你把我的活干了。。。。。。
Imports System.Data.SqlClient
Module Module1
Sub Main()
Dim cnString As String = " Password=123456;User ID=sa;Initial Catalog=学生成绩管理系统;Data Source=QZHENG"
Dim cn As New SqlConnection(cnString) '构造函数
cn.Open()
Dim Sql As String = "select * from 学生信息"
Dim da As New SqlDataAdapter(Sql, cn)
Dim ds As New DataSet
da.Fill(ds, "学生信息")
'这样ds水箱就被填充了,但这个结果集怎么一条一条的取出来来操作呢?这就是我们“复杂地操作它的”的目的。
cn.Close()
Console.ReadKey()
End Sub
End Module
上面只是基础的介绍,更重要的部分在后面,
因为重要的部分是对填充后的DataSet的处理,处理后又是怎么样返回到原来的数据库中的。
自吹自雷这关天,其实一我也是初学者,只不过只写自己理解的,加深一点印象。
因为自学很麻烦,没人交流、没人指点,选个书,看到最后才发现是一个垃圾书,浪费了时间。
遇到一个问题,半天QQ没有回答,又是一个问题。
工作任务重,不能连接学,又是一个困难。
所以兴趣得坚持,问题得脸厚,选书得选准,只选基础的,不打击自己的信心。
尽量用白话来理解,因为没有更多的时间来复习,没有更多的时间来写代码,第一步就跨好。
NND的累,一晚上打N个字,win8还对五笔兼容还不好,还是多多五笔给力!!!
文章TAG:ado net 入门 数据 ADO.net入门(四加载全部内容