1、Visual C数据库编程实战编者的话:关于数据库编程,微软提供了一个统一的数据对象访问模型,在 Visual Studio6.0 中称为 ADO,在.NET 中则统一为 ADO.NET,掌握 ADO.NET 就等于掌握了数据库编程的核心,因此有必要首先复习一下以前发表的ADO.NET 完全攻略 。 针对数据库编程始终是程序设计语言的一个重要方面的内容,也是一个难点。数据库编程的内容十分丰富,但最为基本编程的也就是那么几点,譬如:连接数据库、得到需要的数据和针对数据记录的浏览、删除、修改、插入等操作。其中又以后面针对数据记录的数据操作为重点。本文就来着重探讨一下 Visual C数据库基本编程
2、,即:如何浏览记录、修改记录、删除记录和插入记录。 一程序设计和运行的环境设置: (1).视窗 2000 服务器版 (2).Microsoft Data Acess Component 2.6 以上版本 ( MDAC 2.6 ) (3)Net FrameWork SDK Beta 2 为了更清楚的说明问题,在数据库的选用上,采用了当前比较典型的数据库,一个是本地数据库 Access 2000,另外一个是远程数据库 Sql Server 2000。其中本地数据库名称为“db.mdb“,在其中定义了一张数据表“person“,“person“表的数据结构如下表:字段名称 字段类型 字段意思 id
3、数字 序号 xm 文本 姓名 xb 文本 性别 nl 文本 年龄 zip 文本 邮政编码 远程数据库 Sql Server 2000 的数据库服务器名称为“Server1“,数据库名称为“Data1“,登陆的 ID 为“sa“,口令为空,在数据库也定义了一张“person“表,数据结构如上表。 二如何浏览数据: 在Visual C的数据绑定中,已经了解了如何把数据集中的某些字段绑定到WinForm 组件的某个属性上,这样程序员就可以根据以 WinForm 组件的来定制数据显示的形式,并且此时的 WinForm 组件显示内容就可以随着记录指针的变化而改变。至此可见,浏览数据记录的关键就是如何改变
4、记录指针。要实现这种操作,就要使用到BindingManagerBase 类,此类的主要作用是管理对于那些实现了对同一个数据源进行绑定的对象。说的具体些,就是能够使得 Windows 窗体上的已经对同一数据源进行数据绑定的组件保持同步。在 BindingManagerBase 类中定义了一个属性“Position“,通过这个属性就可以改变 BindingManagerBase 对象中的数据指针。创建BindingManagerBase 对象必须要使用到 BindingContext 类,其实每一个由 Control 类中继承而得到的对象,都有单一的 BindingContext 对象,在大多数
5、创建窗体中实现数据绑定组件的 BindingManagerBase 对象是使用 Form 类的 BindingContext 来得到。下列代码是以 Access 2000 数据库为模型,创建的一个名称为“myBind“的BindingManagerBase 对象。 /创建一个 OleDbConnection string strCon = “ Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = db.mdb“ ; OleDbConnection myConn = new OleDbConnection ( strCon ) ; string s
6、trCom = “ SELECT * FROM person “ ; file:/创建一个 DataSet myDataSet = new DataSet ( ) ; myConn.Open ( ) ; file:/用 OleDbDataAdapter 得到一个数据集 OleDbDataAdapter myCommand = new OleDbDataAdapter ( strCom , myConn ) ; file:/把 Dataset 绑定 books 数据表 myCommand.Fill ( myDataSet , “person“ ) ; file:/关闭此 OleDbConnect
7、ion myConn.Close ( ) ; myBind = this.BindingContext myDataSet , “person“ ; 下列代码是以 Sql Server 2000 数据库为模型,创建一个名称为“myBind“的BindingManagerBase 对象。 / 设定数据连接字符串,此字符串的意思是打开 Sql server 数据库,服务器名称为server1,数据库为 data1 string strCon = “Provider = SQLOLEDB.1 ; Persist Security Info = False ; User ID = sa ; Initi
8、al Catalog = data1 ; Data Source = server1 “ ; OleDbConnection myConn = new OleDbConnection ( strCon ) ; myConn.Open ( ) ; string strCom = “ SELECT * FROM person “ ; file:/创建一个 DataSet myDataSet = new DataSet ( ) ; file:/用 OleDbDataAdapter 得到一个数据集 OleDbDataAdapter myCommand = new OleDbDataAdapter (
9、strCom , myConn ) ; file:/把 Dataset 绑定 person 数据表 myCommand.Fill ( myDataSet , “ person “ ) ; file:/关闭此 OleDbConnection myConn.Close ( ) ; myBind = this.BindingContext myDataSet , “person“ ; 得到了是同一数据源的 BindingManagerBase 对象,通过改变此对象的“Position“属性值,这样绑定数据的组件显示的数据就随之变化,从而实现导航数据记录。 .导航按钮“上一条“实现方法: protec
10、ted void GoPrevious ( object sender , System.EventArgs e ) if ( myBind.Position = 0 ) MessageBox.Show ( “已经到了第一条记录!“ , “信息提示!“ , MessageBoxButtons.OK , MessageBoxIcon.Information ) ; else myBind.Position -= 1 ; . 导航按钮“下一条“实现方法: protected void GoNext ( object sender , System.EventArgs e ) if ( myBind
11、.Position = myBind.Count -1 ) MessageBox.Show ( “已经到了最后一条记录!“, “信息提示!“ , MessageBoxButtons.OK , MessageBoxIcon.Information ) ; else myBind.Position += 1 ; . 导航按钮“至尾“实现方法: protected void GoLast ( object sender , System.EventArgs e ) myBind.Position = myBind.Count - 1 ; . 导航按钮“至首“实现方法: protected void
12、GoFirst ( object sender , System.EventArgs e ) myBind.Position = 0 ; 注释:“Count“是 BindingManagerBase 对象的另外一个重要的属性,是数据集记录的总数。 实战 Visual C数据库编程(中)www.CSharpCN.com 3/29/2003 C#CN三实现删除记录: 在对数据记录进行操作的时候,有二点必须十分清晰: 其一:在对数据记录进行操作的时候,我想有一些程序员一定有这样一个疑惑,当对数据库服务器请求数据集的时候,就会产生“DataSet“对象,用以管理数据集,这样如果这些对数据库服务器的请求
13、非常多,同样也就会产生很多的“DataSet“对象,达到一定时候必然会使得数据库服务器崩溃。这种想法是自然的,但和实际并不相符,因为“DataSet“ 对象并不是在服务器端产生的,而是在客户端产生的。所以面对众多的数据请求的时候对数据库服务器的影响并不十分太大。 其二:记得在用 Delphi 编写三层数据模型的时候的,每一次对数据库的修改其实只是对第二层产生的数据集的修改,要真正修改数据库,还必须调用一个另外的方法。在用 ADO.NET处理数据库的时候,虽然处理的直接对象是数据库,但此时“DataSet“对象中的内容并没有随之改变,而绑定的数据组件显示的数据又来源于“DataSet“对象,这样
14、就会产生一个错觉,就是修改了的记录并没有修改掉,删除的记录并没有删除掉。所以对数据记录进行操作的时候,在修改数据库后,还要对“DataSet“对象进行必要的修改,这样才能保证“DataSet“对象和数据库内容一致、同步。下面代码是删除当前绑定组件显示的记录的程序代码,此代码是以 Access 2000 数据库为模板的: protected void Delete_record ( object sender , System.EventArgs e ) DialogResult r = MessageBox.Show ( “是否删除当前记录!“ , “删除当前记录!“ , MessageBox
15、Buttons.YesNo , MessageBoxIcon.Question ) ; int ss = ( int ) r ; if ( ss = 6 ) / 按动“ 确定“按钮 try file:/连接到一个数据库 string strCon = “ Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = db.mdb “ ; OleDbConnection myConn = new OleDbConnection ( strCon ) ; myConn.Open ( ) ; string strDele = “DELETE FROM pers
16、on WHERE id= “ + t_id.Text ; OleDbCommand myCommand = new OleDbCommand ( strDele , myConn ) ; file:/从数据库中删除指定记录 myCommand.ExecuteNonQuery ( ) ; file:/从 DataSet 中删除指定记录 myDataSet.Tables “person“ . Rows myBind.Position . Delete ( ) ; myDataSet.Tables “person“ . AcceptChanges ( ) ; myConn.Close ( ) ; c
17、atch ( Exception ed ) MessageBox.Show ( “删除记录错误信息: “ + ed.ToString ( ) , “错误! “ ) ; 下面代码是删除当前绑定组件显示的记录的程序代码,此代码是以 Sql Server 2000 数据库为模板的,二者的区别仅仅在于数据链接: protected void Delete_record ( object sender , System.EventArgs e ) DialogResult r = MessageBox.Show ( “是否删除当前记录!“ , “删除当前记录!“ , MessageBoxButtons.
18、YesNo , MessageBoxIcon.Question ) ; int ss = ( int ) r ; if ( ss = 6 ) / 按动“ 确定“按钮 try / 设定数据连接字符串,意思是打开 Sql server 数据库,服务器名称为 server1,数据库为data1 string strCon = “Provider = SQLOLEDB.1 ; Persist Security Info = False ; User ID = sa ; Initial Catalog = data1 ; Data Source = server1 “ ; OleDbConnection
19、 myConn = new OleDbConnection ( strCon ) ; myConn.Open ( ) ; string strDele = “DELETE FROM person WHERE id= “ + t_id.Text ; OleDbCommand myCommand = new OleDbCommand ( strDele , myConn ) ; file:/从数据库中删除指定记录 myCommand.ExecuteNonQuery ( ) ; file:/从 DataSet 中删除指定记录 myDataSet.Tables “person“ . Rows myBi
20、nd.Position . Delete ( ) ; myDataSet.Tables “person“ . AcceptChanges ( ) ; myConn.Close ( ) ; catch ( Exception ed ) MessageBox.Show ( “删除记录错误信息: “ + ed.ToString ( ) , “错误! “ ) ; 在这二段代码中,在更改数据库的同时也对“DatsSet“对象进行了必要的修改。 下图是程序中对数据记录进行删除操作的运行界面: 四插入数据记录: 对数据库进行插入记录操作和删除记录操作基本的思路是一致的,就是通过 ADO.NET 首先插入数据
21、记录到数据库,然后对 “DataSet“对象进行必要的修改。下列代码就是以 Access 2000 数据库为模型修改当前记录的代码:protected void Update_record ( object sender , System.EventArgs e ) int i = myBind.Position ; try file:/连接到一个数据库 string strCon = “ Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = db.mdb “ ; OleDbConnection myConn = new OleDbConnect
22、ion ( strCon ) ; myConn.Open ( ) ; myDataSet.Tables “person“ . Rows myBind.Position . BeginEdit ( ) ; file:/从数据库中修改指定记录 string strUpdt = “ UPDATE person SET xm = “ + t_xm.Text + “ , xb = “ + t_xb.Text + “ , nl = “ + t_nl.Text + “ , zip = “ + t_books.Text + “ WHERE id = “ + t_id.Text ; OleDbCommand m
23、yCommand = new OleDbCommand ( strUpdt , myConn ) ; myCommand.ExecuteNonQuery ( ) ; myDataSet.Tables “person“ . Rows myBind.Position . EndEdit ( ) ; myDataSet.Tables “person“ . AcceptChanges ( ) ; myConn.Close ( ) ; catch ( Exception ed ) MessageBox.Show ( “修改指定记录错误: “ + ed.ToString ( ) , “错误! “ ) ;
24、myBind.Position = i ; 由于对 Sql Server 2000 数据记录修改操作和 Access 2000 数据记录修改操作的差异只在于不同的数据链接,具体的代码可以参考“删除数据记录“ 中的代码,在这里就不提供了。实战 Visual C数据库编程(下)www.CSharpCN.com 3/29/2003 C#CN五插入数据记录: 和前面二种操作在思路是一致的,就是通过 ADO.NET 首先插入数据记录到数据库,然后对“DataSet“对象进行必要的修改。下列代码就是以 Access 2000 数据库为模型插入一条数据记录的代码 protected void Insert_
25、record ( object sender , System.EventArgs e ) try file:/判断所有字段是否添完,添完则执行,反之弹出提示 if ( t_id.Text != “ Data Source = db.mdb“ ; OleDbConnection myConn = new OleDbConnection ( myConn1 ) ; myConn.Open ( ) ; string strInsert = “ INSERT INTO person ( id , xm , xb , nl , zip ) VALUES ( “ ; strInsert += t_id.
26、Text + “, “ ; strInsert += t_xm.Text + “, “ ; strInsert += t_xb.Text + “, “ ; strInsert += t_nl.Text + “, “ ; strInsert += t_books.Text + “)“ ; OleDbCommand inst = new OleDbCommand ( strInsert , myConn ) ; inst.ExecuteNonQuery ( ) ; myConn.Close ( ) ; myDataSet.Tables “person“ . Rows myBind.Position
27、 . BeginEdit ( ) ; myDataSet.Tables “person“ . Rows myBind.Position . EndEdit ( ) ; myDataSet.Tables “person“ . AcceptChanges ( ) ; else MessageBox.Show ( “必须填满所有字段值!“ , “错误!“ ) ; catch ( Exception ed ) MessageBox.Show ( “保存数据记录发生 “ + ed.ToString ( ) , “错误!“ ) ; 同样对 Sql Server 2000 数据库进行插入记录操作和 Acce
28、ss 2000 数据库插入记录操作的差异也只在于不同的数据链接,具体的代码可以参考“删除数据记录“中的代码,在这里就不提供了。 六Visual C数据库编程的完成源代码和程序运行的主界面: 掌握了上面要点,编写一个完整的数据库编程的程序就显得非常容易了,下面是Visual C进行数据库编程的完整代码(Data01.cs),此代码是以 Access 2000 数据库为模型设计的,具体如下: using System ; using System.Drawing ; using System.ComponentModel ; using System.Windows.Forms ; using S
29、ystem.Data.OleDb ; using System.Data ; public class Data : Form private System.ComponentModel.Container components = null ; private Button lastrec ; private Button nextrec ; private Button previousrec ; private Button firstrec ; private TextBox t_books ; private TextBox t_nl ; private ComboBox t_xb
30、; private TextBox t_xm ; private TextBox t_id ; private Label l_books ; private Label l_nl ; private Label l_xb ; private Label l_xm ; private Label l_id ; private Label label1 ; private DataSet myDataSet ; private Button button1 ; private Button button2 ; private Button button3 ; private Button but
31、ton4 ; private BindingManagerBase myBind ; public Data ( ) file:/连接到一个数据库 GetConnected ( ) ; / 对窗体中所需要的内容进行初始化 InitializeComponent ( ) ; file:/清除在程序中使用过的资源 protected override void Dispose( bool disposing ) if( disposing ) if ( components != null ) components.Dispose ( ) ; base.Dispose( disposing ) ;
32、 public static void Main ( ) Application.Run ( new Data ( ) ) ; public void GetConnected ( ) try file:/创建一个 OleDbConnection string strCon = “ Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = db.mdb“ ; OleDbConnection myConn = new OleDbConnection ( strCon ) ; string strCom = “ SELECT * FROM person
33、“ ; file:/创建一个 DataSet myDataSet = new DataSet ( ) ; myConn.Open ( ) ; file:/用 OleDbDataAdapter 得到一个数据集 OleDbDataAdapter myCommand = new OleDbDataAdapter ( strCom , myConn ) ; file:/把 Dataset 绑定 books 数据表 myCommand.Fill ( myDataSet , “person“ ) ; file:/关闭此 OleDbConnection myConn.Close ( ) ; catch (
34、Exception e ) MessageBox.Show ( “连接错误! “ + e.ToString ( ) , “错误“ ) ; private void InitializeComponent ( ) file:/添加控件,略 this.Name = “Data“ ; this.Text = “Visual C的数据库编程!“ ; this.ResumeLayout(false) ; myBind = this.BindingContext myDataSet , “person“ ; protected void New_record ( object sender , Syste
35、m.EventArgs e ) t_id.Text = ( myBind.Count + 1 ).ToString ( ) ; t_xm.Text = “ ; t_xb.Text = “ ; t_nl.Text = “ ; t_books.Text = “ ; protected void Insert_record ( object sender , System.EventArgs e ) try file:/判断所有字段是否添完,添完则执行,反之弹出提示 if ( t_id.Text != “ Data Source = db.mdb“ ; OleDbConnection myConn
36、= new OleDbConnection ( myConn1 ) ; myConn.Open ( ) ; string strInsert = “ INSERT INTO person ( id , xm , xb , nl , zip ) VALUES ( “ ; strInsert += t_id.Text + “, “ ; strInsert += t_xm.Text + “, “ ; strInsert += t_xb.Text + “, “ ; strInsert += t_nl.Text + “, “ ; strInsert += t_books.Text + “)“ ; Ole
37、DbCommand inst = new OleDbCommand ( strInsert , myConn ) ; inst.ExecuteNonQuery ( ) ; myConn.Close ( ) ; myDataSet.Tables “person“ . Rows myBind.Position . BeginEdit ( ) ; myDataSet.Tables “person“ . Rows myBind.Position . EndEdit ( ) ; myDataSet.Tables “person“ . AcceptChanges ( ) ; else MessageBox
38、.Show ( “必须填满所有字段值!“ , “错误!“ ) ; catch ( Exception ed ) MessageBox.Show ( “保存数据记录发生 “ + ed.ToString ( ) , “错误!“ ) ; protected void Update_record ( object sender , System.EventArgs e ) int i = myBind.Position ; try file:/连接到一个数据库 string strCon = “ Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = db
39、.mdb “ ; OleDbConnection myConn = new OleDbConnection ( strCon ) ; myConn.Open ( ) ; myDataSet.Tables “person“ . Rows myBind.Position . BeginEdit ( ) ; file:/从数据库中修改指定记录 string strUpdt = “ UPDATE person SET xm = “ + t_xm.Text + “ , xb = “ + t_xb.Text + “ , nl = “ + t_nl.Text + “ , zip = “ + t_books.
40、Text + “ WHERE id = “ + t_id.Text ; OleDbCommand myCommand = new OleDbCommand ( strUpdt , myConn ) ; myCommand.ExecuteNonQuery ( ) ; myDataSet.Tables “person“ . Rows myBind.Position . EndEdit ( ) ; myDataSet.Tables “person“ . AcceptChanges ( ) ; myConn.Close ( ) ; catch ( Exception ed ) MessageBox.S
41、how ( “修改指定记录错误: “ + ed.ToString ( ) , “错误!“ ) ; myBind.Position = i ; protected void Delete_record ( object sender , System.EventArgs e ) DialogResult r = MessageBox.Show ( “是否删除当前记录!“ , “删除当前记录!“ , MessageBoxButtons.YesNo , MessageBoxIcon.Question ) ; int ss = ( int ) r ; if ( ss = 6 ) / 按动“确定“按钮
42、try file:/连接到一个数据库 string strCon = “ Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = db.mdb “ ; OleDbConnection myConn = new OleDbConnection ( strCon ) ; myConn.Open ( ) ; string strDele = “DELETE FROM person WHERE id= “ + t_id.Text ; OleDbCommand myCommand = new OleDbCommand ( strDele , myConn )
43、 ; file:/从数据库中删除指定记录 myCommand.ExecuteNonQuery ( ) ; file:/从 DataSet 中删除指定记录 myDataSet.Tables “person“ . Rows myBind.Position . Delete ( ) ; myDataSet.Tables “person“ . AcceptChanges ( ) ; myConn.Close ( ) ; catch ( Exception ed ) MessageBox.Show ( “删除记录错误信息: “ + ed.ToString ( ) , “错误!“ ) ; file:/按钮
44、“尾记录“对象事件程序 protected void GoLast ( object sender , System.EventArgs e ) myBind.Position = myBind.Count - 1 ; file:/按钮“下一条“对象事件程序 protected void GoNext ( object sender , System.EventArgs e ) if ( myBind.Position = myBind.Count -1 ) MessageBox.Show ( “已经到了最后一条记录!“, “信息提示!“ , MessageBoxButtons.OK , Me
45、ssageBoxIcon.Information ) ; else myBind.Position += 1 ; file:/按钮“上一条“对象事件程序 protected void GoPrevious ( object sender , System.EventArgs e ) if ( myBind.Position = 0 ) MessageBox.Show ( “已经到了第一条记录!“ , “信息提示!“ , MessageBoxButtons.OK , MessageBoxIcon.Information ) ; else myBind.Position -= 1 ; file:/
46、按钮“首记录“对象事件程序 protected void GoFirst ( object sender , System.EventArgs e ) myBind.Position = 0 ; 对于以 Sql Server 2000 数据库为模型的程序代码,只要把 Data01.cs 中的数据链接,即: string myConn1 = “ Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = db.mdb“ ; 改换成: string strCon = “Provider = SQLOLEDB.1 ; Persist Security Info = False ; User ID = sa ; Initial Catalog = data1 ; Data Source = server1 “ ; 注释:此数据链接代表的意思是:打开 Sql server 数据库,服务器名称为server1,数据库为 data1 就可以得到 Visual C针对 Sql Server 2000 数据库为模板编程的完成源程序代码了。所以本文就不再提供了。 七总结: 数据库编程始终是程序编程内容中的一个重点和难点。而以上介绍的这些操作又是数据库编程中最为基本,也是最为重要的内容。那些复杂的编程无非是以上这些处理的若干个叠加。