关于ADO.NET数据访问方式编程的研究

2010-05-25 01:29吴昌钱
海峡科学 2010年3期
关键词:语句编程组件

吴昌钱



关于ADO.NET数据访问方式编程的研究

吴昌钱

华侨大学计算机学院

该文研究两个方面的内容:(1)研究ADO.NET模型,对各组成部分作分析。(2)具体分析在不同数据访问情况下,如何选择ADO.NET中的组件来编程实现对数据访问操作。其中,理解ADO.NET模型中各组件的实质尤为重要。只有充分理解ADO.NET模型,才能确保在针对不同的数据访问情形下不会选错ADO.NET组件,或选择最适合的组件编写出高效率的代码。

ADO.NET模型 ADO.NET组件 ADO.NET数据访问

NET Framework类库中包含的一整套数据访问技术,用于提供对关系数据和XML的访问,这就是ADO.NET。ADO.NET是Microsoft为大型分布式环境设计而引入,是基于原来ADO提出的全新的、更灵活的新技术,适用于.NET应用程序各种数据的存储。它支持XML编程模型,采用XML作为数据交换格式,因而可以非常顺利地通过防火墙,任何遵循此标准的程序都可以用它进行数据处理和通信,与操作系统平台无关,与语言也无关。

1 ADO.NET模型的组成分析

图1 ADO.NET模型的简要模型

图1为ADO.NET模型的简要模型,关于DataSet对XML文件的操作,图中并没有列出,这里重点体现的是ADO.NET如何从后台服务器的数据库中获得数据,实现对数据的操作。

1.1 ADO.NET对象模型的构成

1.1.1物理层数据库。保存在物理设备(如硬盘)中数据,主要是关系型数据库,这些数据由后台数据库服务器维护。

1.1.2数据提供程序。它实现将物理数据到逻辑数据的转化。

1.1.3数据集。即逻辑数据,是物理数据库在本地的一个副本,数据以XML的形式存储位于内存中,由表、视图等对象构成。

1.1.4数据使用程序(应用程序界面)。主要指Windows应用程序的form窗体界面或web应用程序的网页界面,属于前台应用程序部分。

1.2 Connection组件(连接组件)

实现前台应用程序对后台物理数据库的定位,必须包括对数据库服务器名后IP的定位信息,以及对数据库的定位信息。即先找到服务器,再找到数据库。此外,还包括provider(提供者)、登录方式等信息。

ADO.NET提供了两种数据访问的模式。即Connection在客户端使用数据时,Connection与数据库服务器是否处于连着的状态区分为两种访问模式。一种为连接模式(Connected),另一种为非连接模式(Disconnected)。过去ADO技术只支持连接模式,相比于传统的数据库访问模式,非连接的模式为我们提供了更大的可升级性和灵活性。ADO.NET支持连接模式和非连接模式下的数据库访问,但ADO.NET主要是为了在非连接的环境中连接数据而特别设计的。在非连接模式下,使用的是应用程序服务器内存中的逻辑数据库,即DataSet中的数据。如果没有逻辑数据库(不使用DataSet)也就不能实现非连接情况下数据访问,即对于使用DataReader就只能是ADO.NET的连接模式数据访问。

此外,ADO.NET对于采取连接和非连接数据访问,对Connection连接组件与数据库服务器的连接与断开控制操作不同。在连接模式的环境下,Connection的通/断由ADO.NET自动控制,这可使用以下语句获得验证:

protected void Page_Load(object sender, EventArgs e)

{

SqlConnection conn = new SqlConnection(连接字符串);

SqlDataAdapter da = new SqlDataAdapter("select * from products",conn);

DataSet ds = new DataSet();

Response.Write(conn.State.ToString());//语句(1)

da.Fill(ds);// 语句(2)

Response.Write(conn.State.ToString());//语句(3)

GridView1.DataSource = ds;

GridView1.DataBind();

}

以上,“语句(1)”、“语句(3)”的结果为输出了Closed,且Gridview1中显示了表的数据,这说明“语句(2)”执行成功,完成了物理数据到内存逻辑数据的转化。即执行“语句(2)”时,ADO.NET自动控制了Connection组件的通/断。对于ADO.NET的连接模式就地使用以下代码进行数据访问了,要显示地控制Connection组件的通/断。

SqlConnection conn = new SqlConnection(连接字符串);

SqlCommand cmdAuthors = new SqlCommand("select * from products",conn);

try

{ conn.Open();

SqlDataReader dr= cmdAuthors.ExecuteReader();

GridView1.DataSource=dr;

GridView1.DataBind();

}

finally

{ conn.Close(); }

1.3 Command与DataAdapter

Command组件的名为命令组件,这也就意味着它的功能与4种命令(Select、Update、Delect、Insert)有关,即指明操作的命令语句,实现物理数据到逻辑数据的转化。

DataAdapter组件的名称叫作适配器组件,这也能够明确它的功能,即实现物理数据到逻辑数据的映射转化。所以在采用DataAdapter组件时可以不使用Command组件。其实,DataAdapter组件是一种复合型组件,它包含4个具体的Command,即SelectCommand、UpdateCommand、DelectCommand、InsertCommand。

1.4 DataSet与DataReader

DataSet与DataReader存在以下异同。

1.4.1相同点。DataSet与DataReader中的数据同处内存中,同样是存放记录的逻辑形式数据。

1.4.2不同点

(1)他们的执行数据处理的复合不同。前者存放的是DataTable形式的若干条记录数据,后者在某个时刻内存中每次只存一条记录。DataReader是属于低开销的对象。

(2)它们的工作原理不同。前者为集合数据操作,后者为流式数据操作。前者存放的逻辑数据,可以以整张表的形式进行操作,这点从他们的英文名称就能了解到,“SET”为集合型操作。后者在某个时刻内存中每次只存一条记录,即使是一条记录,它也是按字段逐个读取。SELECT 命令获取查询的数据, 通过DataReader 对象的属性和方法, 将获取的数据以只读方式从当前的数据记录顺向逐条处理, DataReader对象相当于是只读/只向前移的游标,读取规则类似于象棋中兵的走法,每次只能向前一步,不得向后。所以对于编程时,需要注意,Datareader应使用以下形式的语句结构进行数据读取操作:

while (dr.Read()) //dr为DataReader对象

{行数据操作}

(3)它们与数据库服务器的连接状态不同,即数据访问的模式不同。DataSet使用连接模式(Connected),DataReader使用非连接模式(Disconnected)。这点可以想象,基于DataReader每次只存放一条记录,如果是要读取执行select语句后返回的多条记录,DataReader使用的连接组件与数据库服务器以频繁的“断开/连接”方式实现对多条记录的操作是不可取的。

(4)它们对数据的操作能力不一样。前者能对数据进行查询和更新操作。后者只能以read(即查询)的方式操作数据,这点从他们的英文名称就能了解到,是“dataReader”,并非“DataWriter”。

(5)它们读取数据的速度不同。DataSet与DataReader 的复合不同,决定了他们的读取速度不同,在只对数据进行读取时,建议使用DataReader。

2 以编程的方式正确使用ADO.NET模型中的组成

下面以ADO.NET模型中组件的关联关系,给出数据的访问路径。明确这些数据访问路径,对于提高ADO.NET编程效率有很好的帮助。保证能够在访问不同形式数据时选择正确的ADO.NET组件。

2.1 以集合操作的方式访问数据

2.1.1读取

(1)数据库——>Connection——>DataAdapter——>Dataset——>界面

(2)数据库——>Connection——>Command(赋予select语句)——>DataAdapter——>Dataset——>界面

(3)数据库——>Connection——>DataAdapter对象.SelectCommand——>Dataset——>界面

以上三个读取数据的组件使用方式,适合于以集合操作的方式读取多条记录或单条记录数据。数据感知组件可以是列感知组件,如DataList、DropDownList等,也可以其他的数据感知组件,如Datagrid、GridView、Repeater等。

2.1.2更新

(1)DataAdapater对象. Update(需要更新的对象)

对于以上三种读取的数据,在进行更新回数据库服务器时,如果直接使用DataAdapter对象的Update方法时,程序会出现异常。由于以上三种读取的数据在以编程的方式创建DataAdapter时只设置了SelectCommand属性,没有设置UpdateCommand,DeleteCommand和InsertCommand这三个命令属性,ADO.NET并不会根据所提供的SelectCommand对象,创建其他具有更新功能的Command组件。这不同于使用可视化方式创建ADO.NET对象。如果是可视化方式操作的,在指定Select语句的情况下,更新功能的Command组件可以由ADO.NET连接向导自动生成。为此,我们需要创建一个CommandBuilder对象为表的更新自动生成SQL语句。语法如下:

CommandBuilder commandbuild对象=New Command

Builder(DataAdapater对象);

以下示例完成数据的读取,并采用DataAdapater对象完成数据的更新,代码如下:

SqlConnection conn ; SqlDataAdapter da;

DataSet ds ,dsChange; // dsChange用于获取用户作更新的数据

private void Page_Load(object sender, System.EventArgs e)//读取数据

{conn = new SqlConnection(连接字符串);

da = new SqlDataAdapter("select * from Customers", conn);

ds = new DataSet();

dsChange = new DataSet();

da.Fill(ds,"Tb_Customers");

DataGrid1.DataSource = ds;

DataGrid1.DataBind();

}

private void Btn1_Click(object sender,System.EventArgs e)//更新数据

{dsChange=ds.GetChanges();

if(dsChange!=null)

{try

{SqlCommandBuilder CB =new SqlCommandBuilder(da);

da.Update(ds.Tables["Tb_Customers"]);

ds.Tables["Tb_Customers"].Clear();

da.Fill(ds," Tb_Customers");

Response.Write(ds.Tables["Tb_Customers"].TableName );

Page.DataBind();

Response.Write("成功修改记录"

+dsChange.Tables["Tb_Customers"].Rows.Count.ToString()+"条");

}

catch (System.Exception err)

{Response.Write(err.Message); }

}

}

(2)界面——>Command对象——>Connection——>数据库

此方式为直接使用Command对象将客户端数据更新回物理数据库。以下继续上述示例,采用Command对象完成删除记录功能。代码如下:

private void Btn2_Click(object sender,System.EventArgs e)//删除记录

{int effect_Line=0;

SqlCommand cm=new SqlCommand("Delete from Customers where CustomerID='10249' ",conn);

conn.Open();

effect_Line=cm.ExecuteNonQuery();

conn.Close();

if (effect_Line>0)

{Response.Write("成功删除记录"+effect_Line.ToString()+"条");

//以下代码实现刷新数据

ds.Tables["Tb_Customers"].Clear();

da.Fill(ds, "Tb_Customers");

Page.DataBind();

}

}

对于以上两种更新数据的方法,适用的环境有所区别。在前端应用程序的数据感知组件为可编辑情况下,采用前种方式,可以实现将数据感知组中对数据的多个修改一次性保存回物理数据库服务器。如在DataGrid或GridView中对多条记录数据进行编辑,而后提交保存。如果是单条记录的更新,则可以选用后种更新方式。

2.2 以流式操作的方式读取

读取:数据库——>Connection——>Command——>DataReader——>界面

适合于以流式操作的方式读取多条记录或单条记录数据。数据感知组件与采用集合操作方式时使用的组件相同。但是采用流式读取操作数据,主要是为了数据的读取。ADO.NET并不提供流式写入数据。虽然在理论上,对于数据保存回数据库服务器是可行的,但是没有必要,因为如果想被读到客户端的数据能被更新回后台数据库服务器,采用集合的操作方式就足以完成了。此外,对于采用流式数据写回后台数据集库服务器,这在技术上的确也是比较麻烦的。但是在以流式操作的方式读取的是单一记录的数据,如果需要保存还是可以考虑上面提到的“界面——>Command对象——>Connection——>数据库”这一更新数据方式,效率也不低。

3 小结

从ADO.NET模型和ADO.NET数据访问组件的选用两个方面对ADO.NET进行了编程层次上的研究,明确这两个方面对于使用ADO.NET进行数据访问编程,提高编程效率有一定的帮助。

[1] 微软公司. 面向.NET的Web应用程序设计[M].北京:高等教育出版社,2004.

[2] [美]Shawn Wildermuth.周靖,译. ADO.NET实用指南——面向Internet世界的数据访问技术[M].北京: 清华大学出版社,2003.

猜你喜欢
语句编程组件
无人机智能巡检在光伏电站组件诊断中的应用
编程,是一种态度
元征X-431实测:奔驰发动机编程
编程小能手
重点:语句衔接
新型碎边剪刀盘组件
纺织机上诞生的编程
U盾外壳组件注塑模具设计
风起新一代光伏组件膜层:SSG纳米自清洁膜层
如何搞定语句衔接题