写在前面的
- 这篇文章是我在学习ADO.NET中对其中一些非常基本的实用类进行的一次大规模的总结,属于工具类型的博客,需要的小伙伴可以直接进行查询和使用,也欢迎大家进行纠错和更正,同时也希望大家能看完之后留下自己的收获。
介绍
与.NET的联系
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'打开和关闭一个SqlConnection'</span>
SqlConnection sql = new SqlConnection();
sql.ConnectionString = <span class="hljs-decorator" style="color: rgb(0, 102, 102); box-sizing: border-box;">@"Data Source=.\SQLExpress;" + "Initial Catalog=User;......";</span>
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'普通的链接字串这里就不在赘述了'</span>
sql.Open();
.
.
.
sql.Close();
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'使用Using()语法除外,其可以自动关闭打开的链接'</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>
链接对象
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 类
Parameter 类
DataAdapter 类
- DataAdapter类代表了微软数据访问的模型的一个新概念。而且,DataAdapter对象充当数据库和ADO.NET对象模型中非连接对象之间的桥梁。应用DataAdapter类可以将查询结果引入DataSet或者DataTable中,一边能够脱机处理数据。而且也可以将DataSet中对数据库的更改提交。
非链接对象
DataTable 类
-
ADO.NET的DataTable与ADO和DAO中的Recordset对象非常类似。DataTable对象允许哦他能够过行和列的集合查看数据。可以通过调用DataAdapter对象的Fill方法将查询结果存储在DataTable中。
- 举个例子:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">string conn,sql;
conn = <span class="hljs-decorator" style="color: rgb(0, 102, 102); box-sizing: border-box;">@"Data Source = .\SQLExpress;" +"Initial Catalog = Student;Integrated Security = True;";</span>
sql=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SELECT StudentID
FROM Student"</span>;
SqlDataAdapter da = new SqlDataAdapter(sql,conn);
DataTable tbl = new DataTable();
da.Fill(tbl);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
从代码就非常用意看出,在从数据库中独处数据之后,将这些数据都存放在了DataTable中,在此之后,数据就从服务器断开连接,即采用脱机方式进行数据处理,其他用户对于数据的修改是看不到的。
DataColumn 类
-
每个DataTable都有一个Columns集合,该集合是DataColunm对象的容器。从其名称可以看出,一个DataColumn对象对应表中的一列。然而,我们可以这么理解,DataColumn并没有存储DataTable中的数据内容,而是存储了DataTable中的该列的结构信息。
同时,我们称这种类型的信息为元数据,即管理数据的数据(信息)。例如:DataType属性,该类描述了该列所存储的数据类型。
-
DataColumn类还有一个Expression属性,可以用来指定如何计算列中的数据。
-
举个例子:如果我们在调用数据库中的数据的同时,需要计算某两列的值,那么我们一般的做法如下
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">SELECT Cash,Time,
Cash * Time AS TotalMoney
FROM Student</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
但是,这种做法的缺点在于,计算值存在与SQL语句执行的时候。如果修改了DataTalbe对象中的Cash和Time列的内容,TotalMoney列不会发生任何变化。
所以,ADO.NET的DataColum类定义了一个Expression属性来处理类似于这类的任务。当基于一个表达式来检查DataColumn对象的值时,ADO.NET会计算该表达式,并返回一个最新计算值。
-
举个例子:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">DataColumn col = new DataColumn();
col.ColumnName = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"TotalMoney"</span>;
col.DataType = typeof(Decimal);
col.Expression=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Cash * Time"</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
看到这里,是不是感觉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类的默认属性,所以可以隐式使用。
- 举个例子:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">DataRow row;
row =tbl.Rows[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];
Console.WriteLine(row[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]);
Console.WriteLine(row[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Cash"</span>]);
Console.WriteLIne(row[MyTable.Columns[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Cash"</span>]]);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
看完例子,我们不难看出,与Recordset相比最明显的差异DataTable通过DataRows集合使用所有数据行都可用,而不是仅为当前行返回数据。在Recordset中我们一次只能对一行数据进行想要的操作,然后需要使用诸如MoveNext等方法来浏览其他的内容。当然了想要在Recordset中实现这样的功能,循环是必不可少的了。
- 为了能让原来的Recordset和ADO.NET中的数据处理体现差别我们分别举出两个例子。
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'VB实现'</span>
Dim strConn As String, strSQL As String
Dim rs As ADODB.Recordset
strConn = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Provider = SQLOLEDB;Data Source = .\SQLExpress;Initial Catalog = Student; Integrated Security =SSPI;"</span>
strSQL = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SELECT Cash,Time FROM Student"</span>
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open strSQL, strConn, adOpenStatic, adLockReadOnly, adCmdText
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'前面可以忽略= ='</span>
Do While Not rs.EOF
Debug.Print rs(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Cash"</span>)
rs.MoveNext
Loop
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'实现循环遍历'</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>
为了体现区别,我们再来看看ADO.NET中是如何实现的吧:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">string strSQL, strConn;
strConn = <span class="hljs-decorator" style="color: rgb(0, 102, 102); box-sizing: border-box;">@"Data Source= .\SQLExpress;Initial Catalog = Student;Integrated Security = True;";</span>
strSQL = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SELECT Cash,Time FROM Student"</span>;
SqlDataAdapter da = new SqlDataAdapter(strSQL, strConn);
DataTable tbl = new DataTable();
da.fill(tbl);
foreach (DataRow row <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> tbl.Rows)
Console.WriteLine(row[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Cash"</span>])</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
-
同时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对象之间的关系。
- 我们通过一个例子来说明一下:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">DataSet ds;
DataTable tblUser,tblBasicData;
DataRelation rel;
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'创建并初始化DataSet'</span>
rel = ds.Relations.Add(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"User_Type"</span>,tblUser.Columns[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"User"</span>],tblBasicData.Columns[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Type"</span>]);
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'建立User与BasicData表中的User_Type(用户与用户类型)联系'</span>
foreach (DataRow rowUser <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> tblUser.Rows)
{
Console.WriteLine(rowUser[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"UserName"</span>]);
foreach(DataRow rowBasicData <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> rowUser.GetChildRows(rel))
Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"{0}"</span>,rowBasicData[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Type"</span>]);
Console.Read();
}
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'通过一个循环展示出这个关系的效果'</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>
DataView 类
写在后面的
-
首先非常感谢能够耐心的看完这篇文章的人,我也相信通过这一大篇总结,可以让刚刚接触ADO.NET,并且想要了解其中一些基本知识的人有一个对ADO.NET在SQL中的常用类的了解。
-
其次,通过对其中一些类的初步了解,我们还可以根据自己的改造用出不同的效果
-
最后,希望这篇工具类型的文章能够真正的帮助到阅读和查询的人,同时我也会在之后的ADO.NET文章中对其中的一些类做出具体的应用解释。