写在前面的
- 这篇文章是我在学习ADO.NET中对其中一些非常基本的实用类进行的一次大规模的总结,属于工具类型的博客,需要的小伙伴可以直接进行查询和使用,也欢迎大家进行纠错和更正,同时也希望大家能看完之后留下自己的收获。
介绍
设计ADO.NET的目的就是为了帮助开发人员在开发上使用的搞下多层数据库应用程序,而且ADO.NET对象模型也提供了这样的手段。ADO.NET的对象模型大体分为两类:连接类与非连接类。具体的包含关系如图所示:
连接类:该类对象直接与数据库通信,以便于管理连接和和事务,以及从数据库检索数据和向数据库提交所做的更改。
非连接类:允许用户脱机处理数据。
与.NET的联系
提到.NET,ADO在.NET中的应用也就是引用命名空间了,图例如下:
对于SQL来说,在.NET中打开SQL链接的方法并不是很复杂,下面通过一个非常简单的一段代码来说明一下
'打开和关闭一个SqlConnection'
SqlConnection sql = new SqlConnection();
sql.ConnectionString = @"Data Source=.\SQLExpress;" + "Initial Catalog=User;......";
'普通的链接字串这里就不在赘述了'
sql.Open();
.
.
.
sql.Close();
'使用Using()语法除外,其可以自动关闭打开的链接'
链接对象
ProviderFactory 类
- ProviderFactory 类是ADO.NET2.0中新添加的类,相当于一个对象工厂,是开发人员能够为.NET数据提供程序创建其他类的实例。每个ProviderFactory类都提供一种Create方法,此方法创建Connections,ConnectionStringBuilders,Commands,Parameters,DataAdapters和CommandBuilders。
Connection 类
- Connection 对象表示与数据元之间的链接。可通过Connection 类的各种不同属性(property)指定数据源的类型、位置以及其他属性(attribute)。Connection对象大致相当于ADOConnection对象或DAO Database对象,可用它来建立或断开数据库的链接。*Connection对象起到的渠道*作用,其他对象如DataAdapter和Command对象通过它与数据库通信,以提交查询并获取查询结果。
ConnectionStringBuilder 类
这个类也是ADO.NET2.0中新增添的类,它的作用就是简化了为.NET数据提供程序建立连接字符串的过程。简单来说就是这个类公开了一些属性,这些属性对应于可以在.NET数据提供程序的链接字符串中使用的选项。拿OdbcConnectionStringBuilder类公开一个Driver属性,OleDbConnectionStringBuilder类公开一个Provider属性。在使用ConnectionStringBuilder建立链接字符串以后,就可以利用ConnectionStringBuilder对象的ConncecitonString属性来访问该链接字符串。
所以对一个需要频繁链接不同数据库的程序来说,ConnectionStringBuilder 类无意会大大提高工作效率。
Command 类
重头戏登场了,Command类可以表示对数据库的查询、对存储过程的调用或返回特定表内容的直接请求。而且可以通过Command对象对数据库执行任何一种查询操作。
使用Command对象查询数据库也非常简单。需要先声明Connection属性设置为链接数据库的Connection 对象,然后在CommandText属性中指定查询文本(就是TSQL语句了)。
Command对象还有一个ExecuteReader方法,该方法返回一个DataReader对象,该对象可以用来检查由查询所返回的数据行。
同样,Command类还有一个ExecuteXmlReader,它与ExcuteReader类似,但专门用于处理XML格式返回结果的查询。
DataReader 类
- DataReader用于以最快的速度检索并检查查询所返回的行。可以使用DataReader对想来检查查询结构,一次检查一行。当移动下一行时,前一行的内容就会被放弃。DataReader不支持更新操作。由DataReader返回的数据是只读的。由于DataReader对象支持最小特性集,所以他的速度非常快,而且是轻量级的。
Transaction 类
在数据编程中,有时希望将对数据库所做的更改组织起来,将他们看成一个独立的工作单元,这样的工作但愿就称为事务(transaction)。
- 举个例子,有时我们在对程序进行操作时,我们所做的某些更改和回应,要么两项操作同时发生,要么都不要发生。这里就可以用事务来打到这一个目的。
Parameter 类
个人认为这个类的重量等同于Command。因为没有这个类,就无法让程序对某些固定字符串中的参数做出灵活的修改。
举个例子:
如果我们需要访问数据库中的一个表单:SELECT StudentID,CardID,Sex,Note FROM Student WHERE StudentID='220907'
好了,问题来了,如果我们需要对不同的StudentID进行访问呢?就需要不断的去修改代码,所以我们需要更加高效的方法。
SELECT StudentID,CardID,Sex,Note FROM Student WHERE StudentID=@StudentID
这样就可以在每一次的查询之前给定一个值拱开发人员查询,有利于简化编程,生成效率更高的代码。
DataAdapter 类
- DataAdapter类代表了微软数据访问的模型的一个新概念。而且,DataAdapter对象充当数据库和ADO.NET对象模型中非连接对象之间的桥梁。应用DataAdapter类可以将查询结果引入DataSet或者DataTable中,一边能够脱机处理数据。而且也可以将DataSet中对数据库的更改提交。
非链接对象
DataTable 类
ADO.NET的DataTable与ADO和DAO中的Recordset对象非常类似。DataTable对象允许哦他能够过行和列的集合查看数据。可以通过调用DataAdapter对象的Fill方法将查询结果存储在DataTable中。
- 举个例子:
string conn,sql; conn = @"Data Source = .\SQLExpress;" +"Initial Catalog = Student;Integrated Security = True;"; sql="SELECT StudentID FROM Student"; SqlDataAdapter da = new SqlDataAdapter(sql,conn); DataTable tbl = new DataTable(); da.Fill(tbl);
从代码就非常用意看出,在从数据库中独处数据之后,将这些数据都存放在了DataTable中,在此之后,数据就从服务器断开连接,即采用脱机方式进行数据处理,其他用户对于数据的修改是看不到的。
- 举个例子:
DataColumn 类
每个DataTable都有一个Columns集合,该集合是DataColunm对象的容器。从其名称可以看出,一个DataColumn对象对应表中的一列。然而,我们可以这么理解,DataColumn并没有存储DataTable中的数据内容,而是存储了DataTable中的该列的结构信息。
同时,我们称这种类型的信息为元数据,即管理数据的数据(信息)。例如:DataType属性,该类描述了该列所存储的数据类型。DataColumn类还有一个Expression属性,可以用来指定如何计算列中的数据。
举个例子:如果我们在调用数据库中的数据的同时,需要计算某两列的值,那么我们一般的做法如下
SELECT Cash,Time, Cash * Time AS TotalMoney FROM Student
但是,这种做法的缺点在于,计算值存在与SQL语句执行的时候。如果修改了DataTalbe对象中的Cash和Time列的内容,TotalMoney列不会发生任何变化。
所以,ADO.NET的DataColum类定义了一个Expression属性来处理类似于这类的任务。当基于一个表达式来检查DataColumn对象的值时,ADO.NET会计算该表达式,并返回一个最新计算值。举个例子:
DataColumn col = new DataColumn(); col.ColumnName = "TotalMoney"; col.DataType = typeof(Decimal); col.Expression="Cash * Time";
看到这里,是不是感觉DataColumn对象大致类似于ADO和DAO的Fields集合和Field对象,但是功能比它们都要强大。
Constraint 类
- DataTable类还提供了一种方式,用于对DataTable对象中本地存储的数据设置约束。例如:可以建立一个Constraint对象,确保某一列或多列中的值在DataTable中是唯一的。Constraint对象存在于DataTable对象的Constraints集合中。
DataRow 类
如果需要访问存储在DataTable中的实际值,我们可以用Rows集合,该集合中包含了一组DataRow对象。如果需要查看特定行和特定列中的数据,可以使用适当DataRow对象的Item属性来读取。同时,DataRow提供了Item属性的一些重载定义。可以对DataRow对象的Item属性传递列名,索引值、或者相关联的DataColumn对象来指定可要查看哪一列。需要注意的是,Item是DataRow类的默认属性,所以可以隐式使用。
- 举个例子:
DataRow row; row =tbl.Rows[0]; Console.WriteLine(row[0]); Console.WriteLine(row["Cash"]); Console.WriteLIne(row[MyTable.Columns["Cash"]]);
看完例子,我们不难看出,与Recordset相比最明显的差异DataTable通过DataRows集合使用所有数据行都可用,而不是仅为当前行返回数据。在Recordset中我们一次只能对一行数据进行想要的操作,然后需要使用诸如MoveNext等方法来浏览其他的内容。当然了想要在Recordset中实现这样的功能,循环是必不可少的了。
- 为了能让原来的Recordset和ADO.NET中的数据处理体现差别我们分别举出两个例子。
'VB实现' Dim strConn As String, strSQL As String Dim rs As ADODB.Recordset strConn = "Provider = SQLOLEDB;Data Source = .\SQLExpress;Initial Catalog = Student; Integrated Security =SSPI;" strSQL = "SELECT Cash,Time FROM Student" Set rs = New ADODB.Recordset rs.CursorLocation = adUseClient rs.Open strSQL, strConn, adOpenStatic, adLockReadOnly, adCmdText '前面可以忽略= =' Do While Not rs.EOF Debug.Print rs("Cash") rs.MoveNext Loop '实现循环遍历'
为了体现区别,我们再来看看ADO.NET中是如何实现的吧:
string strSQL, strConn; strConn = @"Data Source= .\SQLExpress;Initial Catalog = Student;Integrated Security = True;"; strSQL = "SELECT Cash,Time FROM Student"; SqlDataAdapter da = new SqlDataAdapter(strSQL, strConn); DataTable tbl = new DataTable(); da.fill(tbl); foreach (DataRow row in tbl.Rows) Console.WriteLine(row["Cash"])
- 举个例子:
同时DataRow 对象所拥有的BeginEdit以及EndEdit方法可以将Item中的属性进行修改后然后保存到该行中。并且可以通过CancelEdit方法来取消当前所做的修改。
DataSet 类
同样,ADO.NET的三大法宝之一(我自己认为的“COMMAND””DATAADAPTER”“DATASET”),这个对象包含了一个数据集,可以将DataSet对象视为许多DataTable对象(存储在DataSet对象的Tables集合中)的容器。
可能对于平时的小程序的编写不能体现出DataSet的威力,但是我们来假设这么一个情景,如果我们需要对一个运行在阿里巴巴服务器上的数据库(SQL)进行维护和数据修改,我们当然不希望对每张表都进行“取—改—存”的操作,我们肯定是需要将修改的表格一次性全部取出,然后同意修改,最后统一提交。那么DataSet就可以帮助我们进行这样的操作。
对于DataSet的其他方法这里就不在过多的说明了。
DataRelation 类
数据库中的表单多多少少都会有些关联,有时候我们在查询的时候总是希望可以在程序中使用多个表单的数据。所以,ADO.NET的解决方式就是通过DataSet对象借助DataRelation类来处理来自相关表单(DataTable)对象的数据。
需要注意的是,DataSet类也公开了一个Relations属性,该属性是DataRelation对象的一个集合。可以使用DataRelation对象来表明DataSet中不同DataTable对象之间的关系。
- 我们通过一个例子来说明一下:
DataSet ds; DataTable tblUser,tblBasicData; DataRelation rel; '创建并初始化DataSet' rel = ds.Relations.Add("User_Type",tblUser.Columns["User"],tblBasicData.Columns["Type"]); '建立User与BasicData表中的User_Type(用户与用户类型)联系' foreach (DataRow rowUser in tblUser.Rows) { Console.WriteLine(rowUser["UserName"]); foreach(DataRow rowBasicData in rowUser.GetChildRows(rel)) Console.WriteLine("{0}",rowBasicData["Type"]); Console.Read(); } '通过一个循环展示出这个关系的效果'
- 我们通过一个例子来说明一下:
DataView 类
类如其名,这也是最后一个类了。DataView提供了在将一组查询结果置于DataTable对象之后以不同方式查看数据的功能。
我们就来介绍几个简单且常用的属性吧:
Sort:对DataTable对象的内容进行排序。如果想要根据某一列对DataTable对象的内容进行排序,只要将DataView的Sort属性设置为该列名称即可。
Filter:使只有符合特定标准的的行可见。
对于DataView类来说最重要的我个人认为就是DataView可以支持多个DataView对象同时对一个DataTable进行查看。这样就极大的增强了数据查看的灵活性。
写在后面的
首先非常感谢能够耐心的看完这篇文章的人,我也相信通过这一大篇总结,可以让刚刚接触ADO.NET,并且想要了解其中一些基本知识的人有一个对ADO.NET在SQL中的常用类的了解。
其次,通过对其中一些类的初步了解,我们还可以根据自己的改造用出不同的效果
最后,希望这篇工具类型的文章能够真正的帮助到阅读和查询的人,同时我也会在之后的ADO.NET文章中对其中的一些类做出具体的应用解释。