一、为什么要学习ADO.NET
1、先来看个例子:
问题是,程序怎么和数据库打交道的呢?
数据库储存了已注册QQ的用户信息。
用户登录时程序在做什么事情?
ADO.NET的作用:
(1)程序要和数据库交互要通过ADO.Net 进行。
(2)通过ADO.Net就能在程序中执行SQL了。
(3)ADO.Net中提供了对各种不同数据库的统一操作接口。
二、ADO.NET的组成
2、ADO:ActiveX Data Objects,ActiveX数据对象,是Microsoft提出的应用程序接口(API)用以实现访问关系或非关系数据库中的数据。
(1)程序端数据集:
DataSet/DataTable/DataRow/DataColumn... 程序用这些个来存放从数据库中查询到的结果集。
- DataSet 相当于数据库里的一个结果集。
- DataTable 相当于数据库里的一张表。
- DataRow 相当于数据库里的一行。
- DataColumn 相当于数据库里的一列。
(2).NET Framework 数据提供程序:
Connection/DataAdapter/DataReader/Command
- Connection 数据库连接。可以理解为到数据库里去的路。
- DataAdapter 适配器。可以理解为程序里的一辆卡车,它到数据库里去能够把一张表所查询到的结果集一次性的搬回来,装到DataSet里(这时的DataSet会占用程序的内存)。
- DataReader 读取器。可以理解为一辆摩托车,把数据库的结果集看作是一个仓库,仓库里有很多箱啤酒,摩托车去每次来回一箱一箱的搬到程序里。
- 区别:卡车是把所有啤酒一次性搬完,摩托车是一箱一箱的搬。一是运载量不同,二是运输方式也不同。
- Command 可以理解为一个操作员,一个员工。如果要用摩托车去运啤酒的话,就由这个员工来骑着一辆摩托车,然后去数据库里去拿数据。而适配器(卡车)它本身配了司机,你只需要打个电话过去那卡车就来了,它就会到数据库里去一次性的把数据搬回来。所以说它们的运输方式也不同。
3、操作举例图:
(1)如果要执行增删改和单个值查询的时候,可以直接让【车间工人】去【中央仓库】做。
(2)如果要从【中央仓库】查询多行货物的时候,有两种方式:
① 可以选择叫一辆【货运卡车】去搬,卡车可以一次性的都搬过来,但【生产车间】一下子用不了,所以卡车就把货先放在【车间临时仓库】,这样车间需要的时候直接拿就可以了。
② 可以让【车间工人】把自己的【摩托车】拿来,骑【摩托车】去仓库拿货,但每次只能拿一行货物,所以需要往返的拿很多次才能拿完。但因为每次只拿一行货物过来,车间就直接使用了,不必存到【车间临时仓库】里。因为【卡车】是一次性搬完的,所以【卡车】运完后【道路】就可以关闭了,可以把这条【道路】(Connection)给其他【卡车】用了。而用【摩托车】搬运时,因为要来回不停的搬,所以【道路】一直开着,这时如果还有其他【摩托车】想要工作,就只能再开另外一条【道路】,即再建一个数据库连接。
4、ADO.NET数据库操作图
(1)Connection 类 :
和数据库交互,你必须连接它。连接帮助指明数据库服务器、数据库名字、用户名、密码,和连接数据库所需要的其它参数。Connection对象会被Command对象使用,这样就能够知道是在哪个数据源上面执行命令。
与数据库交互的过程意味着你必须指明想要执行的操作。这是依靠Command对象执行的。你使用Command对象来发送SQL语句给数据库。Command对象使用Connection对象来指出与哪个数据源进行连接。你能够单独使用Command对象来直接执行命令,或者将一个Command对象的引用传递给DataAdapter,它保存了一组能够操作下面描述的一组数据的命令。
(2)Command对象 :
成功与数据建立连接后,就可以用Command对象来执行查询、修改、插入、删除等命令; Command对象常用的方法有ExecuteReader方法、ExecuteScalar()方法和ExecuteNonQuery()方法;插入数据可用ExecuteNonQuery()方法来执行插入命令。
(3)DataReader类 :
许多数据操作要求你只是读取一串数据。DataReader对象允许你获得从Command对象的SELECT语句得到的结果。考虑性能的因素,从DataReader返回的数据都是快速的且只是“向前”的数据流。这意味着你只能按照一定的顺序从数据流中取出数据。这对于速度来说是有好处的,但是如果你需要操作数据,更好的办法是使用DataSet。
(4)DataSet对象 :
DataSet对象是数据在内存中的表示形式。它包括多个DataTable对象,而DataTable包含列和行,就象一个普通的数据库中的表。你甚至能够定义表之间的关系来创建主从关系(parent-child relationships)。DataSet是在特定的场景下使用——帮助管理内存中的数据并支持对数据的断开操作的。DataSet是被所有Data Providers使用的对象,因此它并不像Data Provider一样需要特别的前缀。
(5)DataAdapter类 :
某些时候你使用的数据主要是只读的,并且你很少需要将其改变至底层的数据源。同样一些情况要求在内存中缓存数据,以此来减少并不改变的数据被数据库调用的次数。DataAdapter通过断开模型来帮助你方便的完成对以上情况的处理。当在一单批次的对数据库的读写操作的持续的改变返回至数据库的时候,DataAdapter 填充(fill)DataSet对象。DataAadapter包含对连接对象以及当对数据库进行读取或者写入的时候自动的打开或者关闭连接的引用。另外,DataAdapter包含对数据的SELECT、INSERT、UPDATE和DELETE操作的Command对象引用。你将为DataSet中的每一个Table都定义DataAadapter,它将为你照顾所有与数据库的连接。所有你将做的工作是告诉DataAdapter什么时候装载或者写入到数据库。
(6)DataTable类 :
DataTable 是一个数据网格控件,理解成一张表就可以了。
DataTable的实例化以及添加列:
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Name");
DataRow dr = dt.NewRow();
object[] objs = { 1, "Name" };
dr.ItemArray = objs;
dt.Rows.Add(dr);
this.dataGridView1.DataSource = dt;
5、数据库的打开和关闭问题,只有适配器不用我们手动的去打开和关闭,其他的都需要我们手动的去打开和关闭。