1、第 7章 获取数据7.1 ADO.NET 简介ADO.NET 是与 C#和 Microsoft.NET framework 一起使用的类集的名称,用于以关系型的、面向表的格式访问数据。这包括关系数据库,比如 Microsoft Access 和 SQL Server,以及其他数据库, 甚至还包括非关系数据源。ADO.NET被集成到.NET framework,用于.NET 语言。 ADO.NET 包含 System.Data 名称空间中的一组对象,System.Data 名称空间可以通过 .NET 的数据提供者(provider )与数据库通信。ADO.NET 的名称来源于 ADO(Activ
2、eX Data Objects) ,这是用途广泛的类组,用于在以往的 Microsoft 技术中访问数据。之所以使用 ADO.NET 名称,是因为 Microsoft 希望表明,这是在 .NET 编程环境中优先使用的数据访问接口。ADO.NET 的主要目标是提供对关系数据的简单访问功能。 ADO.NET 提供两个核心组件:DataSet 和.NET 数据提供者程序。ADO.NET DataSet 组件为 ADO.NET 提供断开式结构服务,它的设计是为了实现独立于任何数据源的数据访问。因此,它可以用于多种不同的数据源。.NET 数据提供者程序用于连接到数据源,检索、修改数据源中的数据。开发人员
3、可以将检索到的结果放入 ADO.NET DataSet。在实际应用中,.NET 数据提供者程序在数据源和 ADO.NET DataSet 之间起着桥梁的作用。ADO.NET 提供了两种内置的 ADO.NET 数据提供者,一种是 OLE DB.NET数据提供程序,用于使用 OLE DB 公开的数据源(如 Microsoft Access) ,另一种是 SQL Server.NET 提供者程序,用于使用 Microsoft SQL Server7.0 或更高版本。另外,Microsoft 最近预演了用于 ADO.NET 的 ODBC.NET 提供者,它允许.NET访问更多的旧的数据格式和第三方数据
4、库。7.2 使用 ADO.NET 访问数据库7.2.1 ADO.NET 类和对象概述可以把类分为.NET 提供者对象和用户对象。提供者对象专用于每一种类型的数据源;专用于提供者的对象完成在数据源中实际的读取和写入工作。用户对象是将数据读入到内存中后用来访问和操纵数据的对象。用户对象以非连接方式使用;提供者对象要求活动的连接,可以使用它们首先读取数据,然后根据需要,通过用户对象使用内存中的数据,通过使用者对象更新数据源中的数据,并将变动写回到数据源中。7.2.2 提供者对象即在每一个.NET 数据提供者中定义的对象,其名称前带有专用于提供者的名称。1连接对象 Connection连接对象是您要使
5、用的第一个对象,被要求用于任何其他 ADO.NET 对象之前。它提供了到数据源的基本连接。专用于提供者的名称包括用于 SQL Server7.0 的 SqlConnection 和用于 OLE DB 的 OleDbConnection。2 命令对象 Command可以使用此对象发出命令,比如对数据源的查询,专用于提供者的名称包括用于 SQL Server 的 SqlCommand 和用于 OLE DB 的 OleDbCommand。3 CommandBuilder 对象此对象用于构建 SQL 命令,可以在基于单一表查询的对象中进行数据修改。专用于提供者的名称包括用于 SQL Server7.0
6、 的 SqlCommandBuilder 和用于 OLE DB 的 OleDbCommandBuilder。4 DataReader 对象可以从数据源中读取仅能前向和只读的数据流。此对象具有最好的功能,可以简单地读取数据;专用于提供者的名称包括用于 SQL Server7.0 的SqlDataReader 和用于 OLE DB 的 OledbDataReader。5 DataAdapter 对象提供连接 DataSet 对象和数据源的桥梁,DataAdapter 使用 Command 对象在数据源中执行 SQL 命令,对数据源进行各种操作,包括更新变动的数据,填充数据集以及其他操作。专用于提供
7、者的名称包括用于 SQL Server7.0 的SqlDataAdapter 和用于 OLE DB 的 OledbAdapter。7.2.3 用户对象 DataSet此对象表示一组相关表,在应用程序中这些表作为一个单元被引用。有了此对象,就可以快速从每一个表中获取所需要的数据,当与服务器断开时检查并修改数据,然后在一次操作中使用这些修改的数据更新服务器。DataSet 具有属性,使得您可以访问低级对象,这些对象代表单独的表、行、列和关系。这些对象是:1. DataTable 对象此对象代表在 DataSet 中的表。可以在 DataSet 中存储多个 DataTable 对象。2. DataR
8、ow 对象此对象代表来自表的关联数据的行。可以在 DataTable 中存储多个 DataRow 对象。3.DataColumn 对象此对象代表表中的列。可以在 DataRow 中存储多个 DataColumn 对象。4. DataRelation 对象此对象代表通过共享列而发生关系的两个表之间的关系。7.2.4 使用 System.Data 名称空间在 C#代码中使用 ADO.NET 的第一步是引用 System.Data 名称空间,其中含有所有的 ADO.NET 类。1. SQL Server.NET 数据提供者如果您使用的是 SQL Server(版本 7 或更高级的版本)或 MSDE,
9、则通过使用SQL Server 专用的.NET 数据提供者就可以获得最好的性能和对基础性的功能的最直接的访问,按如下方式使用 using 指令可以引用 SQL Server 专用的.NET数据提供者:using System.Data.SqlClient;2. OLE DB.NET 提供者对于不是 SQL Server7.0 或以上版本的大多数数据源(Microsoft Access, Oralce 以及其他数据源)可以使用 OLE DB.NET 数据提供者,按如下方式使用 using 指令引用它:using System.Data.OleDb;*7.3 在 VS 中访问数据例题 1:建立 S
10、QL Server 数据库 student,显示其中一个表 xs 的记录内容,并可查询、修改、删除其记录。 (参见 D:GZC#ado数据库 sql 程序)一 建立 SQL Server 数据库启动 Microsoft SQL Server企业管理器 Microsoft SQL Servers SQL Servers组 local(Windows NT) 右键单击数据库 单击新建数据库输入新建数据库名(student)右键单击 student单击新建表,输入表中各字段定义,确定主键 关闭该窗口并以 xs 为名存储右键单击 xs 表单击打开表 单击返回所有行 输入表中各记录值关闭该窗口。二将 C
11、#应用程序与数据库连接1. 建立数据适配器到数据库的连接在工具箱中单击“数据”标签双击“SqlDataAdapter”,打开“数据适配器配置向导”单击“下一步”选“新建数据库连接” ,打开“数据链接属性”对话框 输入服务器名(选择默认的即可) ,选择“使用 windows 集成安全” ,在服务器上选择数据库“student”,点击“测试连接”按钮,显示“连接成功”单击“确定”单击“下一步”选择“使用 SQL 语句” ,单击“下一步”单击“查询生成器”添加表 xs选“*” ,单击“确定”单击“下一步” 单击“完成”此时,表单下添加了两个对象,即 sqlDataAdapter1 和 sqlConn
12、ection1。数据适配器包含我们希望从数据库中返回的数据的基本信息,是.NET 数据提供者的一个组件,用于将来自数据库的数据填充到 DataSet 中,并将在 DataSet 中的变化返回到数据库中。sqlConnection 对象包含了 ADO.NET 用来连接到数据库的所有信息。2.添加 DataSet右键单击刚才创建的 sqlDataAdapter1选择 “生成数据集”选择“新建”DataSet1,选择“添加到数据集中的表 xs”单击“确定”此时 Form 下添加了一个新的对象 DataSet11,同时,解决方案中添加了一个新文件 DataSet1.xsd。此文件是 DataSet 的
13、模式。XSD(XML 模式定义)模式是一个文档,通过它,我们可以验证 XML 文档的结构,XML 是用于表示数据的文本格式。因为 DataSet 在后台使用 XML 组织数据,此文件由 VS 自动生成,它规定了数据集、每一个表及表之间的关系的结构。3.文本框与数据库数据的绑定在表单上创建文本框 txtxh,在其 DataBindings 属性细目上,单击其 text 部分,出现 datasete11-xs-xh xm,单击“xh”,则 txtxh 与 xs 表中的 xh 字段绑定。同样方法,可将另一个文本框 txtxm 与 xm 字段绑定。这仅仅意味着在文本框中可以看见数据集中的数据,用户在文
14、本框中所作的任何变化都可以反映到 DataSete 中。但这不会影响数据源(即数据库)中的数据,除非用更新命令修改表中数据。4.上述操作仅定义了来自表中的数据的结构,还没有定义实际的数据,下面的命令是通知数据适配器填充 DataSet,即使应用程序获取数据:可单击表单(Form)背景,进入代码编辑器, (或制作一查询按钮,在其事件处理程序中, )写如下代码: this.sqlDataAdapter1.Fill(this.dataSet11,0,0,”xs”);Fill()方法使用来自数据源的数据填充 DataSet 中的 DataTable。此方法带有 4 个参数。第一个参数规定希望填充的 D
15、ataSet,在此就是 dataSet11 。第二个参数规定,应该从第几个记录开始。第三个参数规定返回几个记录。如果设为 0,则返回所有记录。第 4 个参数规定生成数据的表的名称,在此就是 xs。现在,保存并运行该程序,可在文本框中看到 xs 表中的首行记录值。5.添加导航按钮,以便看到表中全部记录。见源程序代码。6.使用 DataGrid 浏览表中所有数据在其 DataSouce 属性中设置 dataset11.xs主要代码如下:static void Main() Application.Run(new Form1();private void Form1_Load(object send
16、er, System.EventArgs e)/this.sqlDataAdapter1.Fill(this.dataSet11,0,0,“xs“);private void btnback_Click(object sender, System.EventArgs e)this.BindingContextthis.dataSet11,“xs“.Position-;private void btnnext_Click(object sender, System.EventArgs e)this.BindingContextthis.dataSet11,“xs“.Position+;priva
17、te void btnupdate_Click(object sender, System.EventArgs e)this.sqlDataAdapter1.Update(this.dataSet11.xs);private void btnqer_Click(object sender, System.EventArgs e)this.dataSet11.Clear();this.sqlDataAdapter1.Fill(this.dataSet11,0,0,“xs“);private void btnreset_Click(object sender, System.EventArgs e
18、)this.dataSet11.Clear();*例题 2:建立 Access 数据库,显示其中一个表的记录内容,并可查询、修改、删除其记录。 (参见 D:GZC#备课Database1 程序)static void Main() Application.Run(new DateBase2();private void Form1_Load(object sender, System.EventArgs e)/this.oleDbDataAdapter1.Fill(this.dataSet11,0,0,“t1“);private void buttonback_Click(object sen
19、der, System.EventArgs e)this.BindingContextthis.dataSet11,“t1“.Position-;private void buttonnext_Click(object sender, System.EventArgs e)this.BindingContextthis.dataSet11,“t1“.Position+;private void buttonupdate_Click(object sender, System.EventArgs e)this.oleDbDataAdapter1.Update(this.dataSet11.t1)
20、;private void buttonq_Click(object sender, System.EventArgs e)this.dataSet11.Clear();this.oleDbDataAdapter1.Fill(this.dataSet11,0,0,“t1“);private void buttonr_Click(object sender, System.EventArgs e)this.dataSet11.Clear();7.4 使用 SQL Server.NET 数据提供者应用举例例题 1:用 ADO.NET 访问 SQL 数据库在数据库魏菊丽20086666中建立stud
21、ent表,其中含sno(主键),sname,ssex,sage,sdept等字段。在Form1中制作一个 comboBox控件,该控件含有CS,IS,MA三个系的选项,让用户通过该控件选择查询学生所在系,在dataGridView控件中显示查询结果。代码详见d:gzc#ado数据库ado_combox2005 程序1.“数据库ado_combox2005”程序界面:2. 其中,控件comboBox1中项目(Items)的设置:3.“数据库ado_combox”程序中“查询按钮”运行结果界面:4.“数据库ado_combox2005”程序代码:/用户添加System.Data.SqlClient
22、,可以引用SQL Server专用的.NET数据提供者using System.Data.SqlClient;/以下button1_Click是“数据库ado_combox”程序“查询”按钮代码private void button1_Click(object sender, System.EventArgs e)/生成连接对象实例thisConnection连接SQL Server数据库魏菊丽20086666SqlConnection thisConnection=new SqlConnection(“Data Source= localhost;Integrated Security=SS
23、PI;Initial Catalog=魏菊丽20086666“);/*创建并返回一个与thisConnection相关联的SqlCommand 对象实例thisCommand,同时获取或设置要对数据源执行的SQL语句*/SqlCommand thisCommand=new SqlCommand(“select * from student where sdept=“+comboBox1.Text+“,thisConnection); /创建一个SqlDataAdapter 对象实例thisAdapterSqlDataAdapter thisAdapter=new SqlDataAdapter(
24、);/获取一个SQL语句,用于在数据源中选择记录thisAdapter.SelectCommand=thisCommand;DataSet thisDataSet=new DataSet();/生成数据集实例thisDataSetthisConnection.Open();/打开本次设置的数据库连接/将以上在数据源中选择的记录的所有行填充到数据集中,仍然命名为表student。thisAdapter.Fill(thisDataSet, “student“);/*设置 dataGridView1的数据源为数据集中的数据*/ this.dataGridView1.DataSource=thisDa
25、taSet.Tables0;thisConnection.Close();/断开本次数据库连接例题 2:用 ADO.NET 访问 SQL 数据库建立 student 数据库,在该库中建立 xs 表,其中含 xh(主键),xm 字段。在 Form1 中制作一个 dataGridView 控件用来浏览数据库表中的数据。制作一个ListBox 用来显示查询结果。制作若干按钮,分别完成浏览、添加、修改、删除、查询表中记录的功能。详见 d:gz.C#课件2006 新教案数据库 sqlado 程序1.本题界面设计如下:2.代码如下:using System;using System.Drawing;usi
26、ng System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;using System.Data.SqlClient;/用户自己添加,可以引用SQL Server专用的.NET数据提供者static void Main() Application.Run(new Form1(); /以下功能是浏览数据库student中的xs表的所有记录private void btnliulan_Click(object sender, System.EventArgs e)/用Sq
27、lConnection对象实例thisConnection连接SQL Server数据库studentSqlConnection thisConnection=new SqlConnection(“Data Source=localhost;Integrated Security=SSPI;Initial Catalog=student“);/创建一个SqlDataAdapter 对象实例thisAdapteSqlDataAdapter thisAdapter=new SqlDataAdapter();/生成数据集实例DataSet thisDataSet=new DataSet();/创建并
28、返回一个与SqlConnection相关联的SqlCommand 对象SqlCommand thisCommand=thisConnection.CreateCommand();/获取或设置要对数据源执行的SQL语句thisCommand.CommandText=“select xh,xm from xs“;thisAdapter.SelectCommand =thisCommand ;/获取一个SQL语句,用于在数据源中选择记录thisConnection.Open();/打开本次设置的数据库连接/将以上在数据源xs中选择的记录的所有行填充到数据集中,仍然命名为表xs。thisAdapter
29、.Fill(thisDataSet,“xs“);thisConnection.Close();/断开本次数据库连接/*设置 dataGridView1的数据源为数据集中的数据*/this.dataGridView1.DataSource = thisDataSet.Tables0; /以下功能是查询数据库student中的xs表中姓“a”的所有记录/以下代码是显示查询结果的另一种方法,即显示在listBox1中。private void btnchaxun_Click(object sender, System.EventArgs e)this.listBox1.Items.Clear();S
30、qlConnection thisConnection=new SqlConnection(“Data Source=laptop;Integrated Security=SSPI;Initial Catalog=student“);SqlCommand thisCommand=thisConnection.CreateCommand();thisCommand.CommandText=“select xm from xs where xm like a%“;thisConnection.Open();/*ExecuteReader()创建读取器对象,用于读取生成的结果,将带有所包含的结果的该
31、读取器指派给thisReader*/SqlDataReader thisReader=thisCommand.ExecuteReader();/*Read()方法从查询中读取单独的一行数据.若有多个数据要读,则返回true;如果没有,则返回false.*/while(thisReader.Read()/*当Read()返回true时,输出结果。SqlDataReader对象提供索引符属性,允许引用列*/this.listBox1.Items.Add(thisReader“xm“); thisReader.Close();thisConnection.Close();/以下功能是向数据库stud
32、ent中的xs表添加新记录private void btntj_Click(object sender, System.EventArgs e)SqlConnection thisConnection=new SqlConnection(“Data Source=localhost;Integrated Security=SSPI;Initial Catalog=student“);SqlDataAdapter thisAdapter=new SqlDataAdapter();DataSet thisDataSet=new DataSet();SqlCommand thisCommand=th
33、isConnection.CreateCommand();thisCommand.CommandText=“select xh,xm from xs “;thisAdapter.SelectCommand =thisCommand ;thisConnection.Open();SqlCommandBuilder thisBuilder = new SqlCommandBuilder(thisAdapter);thisAdapter.Fill(thisDataSet, “xs“);DataRow thisRow=thisDataSet.Tables“xs“.NewRow();/在数据集的 xs
34、Table中创建新行thisRow“xh“=“555“;thisRow“xm“=“QQ“;/设置新行中的个字段值thisDataSet.Tables“xs“.Rows.Add(thisRow);/将新行添加到数据集的 xs Table中thisAdapter.Update(thisDataSet,“xs“);/ 修改数据库表thisConnection.Close();/以下功能是修改数据库student中的xs表的记录private void btnxg_Click(object sender, System.EventArgs e)SqlConnection thisConnection=
35、new SqlConnection(“Data Source=localhost;Integrated Security=SSPI;Initial Catalog=student“);SqlDataAdapter thisAdapter=new SqlDataAdapter();DataSet thisDataSet=new DataSet();SqlCommand thisCommand=thisConnection.CreateCommand();thisCommand.CommandText=“select xh,xm from xs “;thisAdapter.SelectComman
36、d =thisCommand ;thisConnection.Open();SqlCommandBuilder thisBuilder = new SqlCommandBuilder(thisAdapter);thisAdapter.Fill(thisDataSet, “xs“);thisDataSet.Tables“xs“.Rows5“xm“=“qq“;thisAdapter.Update(thisDataSet,“xs“);thisConnection.Close();/以下功能是删除数据库student中的xs表的记录private void btnsc_Click(object sen
37、der, System.EventArgs e)SqlConnection thisConnection=new SqlConnection(“Data Source=localhost;Integrated Security=SSPI;Initial Catalog=student“);SqlDataAdapter thisAdapter=new SqlDataAdapter();DataSet thisDataSet=new DataSet();SqlCommand thisCommand=thisConnection.CreateCommand();thisCommand.Command
38、Text=“select xh,xm from xs “;thisAdapter.SelectCommand =thisCommand ;thisConnection.Open();SqlCommandBuilder thisBuilder = new SqlCommandBuilder(thisAdapter);thisAdapter.Fill(thisDataSet, “xs“);DataColumn keys=new DataColumn1;keys0=thisDataSet.Tables“xs“.Columns“xh“;/key0的值为该数据集xs Table中的xh值thisData
39、Set.Tables“xs“.PrimaryKey=keys;/设xh为主键DataRow findRow=thisDataSet.Tables“xs“.Rows.Find(“555“);/获取包含指定主键值“555“的行/ Call Update command to mark change in tableif(findRow !=null) /若找到该行findRow.Delete();/删除该行thisAdapter.Update(thisDataSet,“xs“);/修改数据库表thisConnection.Close();private void dataGrid1_Navigat
40、e(object sender, System.Windows.Forms.NavigateEventArgs ne)*7.5 使用 OLE DB.NET 数据提供者应用举例1.使用 ADO.NET 获取表中的数据。(参见 D:GZC#备课DATA 程序)using System;using System.Data;using System.Data.OleDb;namespace DATAclass DataReaderAccessExamplestatic void Main(string args)OleDbConnection thisConnection = new OleDbCon
41、nection(“Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:gzc#备课db1.mdb“);thisConnection.Open();/打开连接对象,建立了到数据库的连接OleDbCommand thisCommand=thisConnection.CreateCommand();/CreateCommand()方法可创建与此连接相关联的命令thisCommand.CommandText =“SELECT xh,xm FROM t1“;/命令本身被指派给命令对象的CommandText属性OleDbDataReader thisReader
42、=thisCommand.ExecuteReader();/*ExecuteReader()创建读取器对象,用于读取生成的结果,将带有所包含的结果的该读取器指派给thisReader*/while(thisReader.Read()/*Read()方法从查询中读取单独的一行数据.若有多个数据要读,则返回true;如果没有,则返回false.*/Console.WriteLine(“t0t1“,thisReader“xh“,thisReader“xm“);/*当Read()返回true时,输出结果OleDbDataReader对象提供索引符属性,允许引用列,作为按列名称的数组引用 */thisR
43、eader.Close();thisConnection.Close();2.使用 ADO.NET 修改表中的数据。(参见 D:GZC#备课 ModiData 程序)sing System;using System.Data;using System.Data.OleDb;namespace UpdatingDataclass Class1static void Main(string args)/ Specify SQL Server-specific connection stringOleDbConnection thisConnection = new OleDbConnection(
44、“Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:gzc#备课db1.mdb“);thisConnection.Open();/ Create DataAdapter object for update and other operationsOleDbDataAdapter thisAdapter = new OleDbDataAdapter( “SELECT xh, xm FROM t1“, thisConnection);/ Create CommandBuilder object to build SQL commandsOleDbComm
45、andBuilder thisBuilder = new OleDbCommandBuilder(thisAdapter);/ Create DataSet to contain related data tables, rows, and columnsDataSet thisDataSet = new DataSet();/ Fill DataSet using query defined previously for DataAdapterthisAdapter.Fill(thisDataSet, “t1“);/ Show data before changeConsole.WriteL
46、ine(“name before change: 0“, thisDataSet.Tables“t1“.Rows0“xm“);/ Change data in t1 table, row 0, xm columnthisDataSet.Tables“t1“.Rows0“xm“ = “ppp“;/ Call Update command to mark change in tablethisAdapter.Update(thisDataSet, “t1“);Console.WriteLine(“name after change: 0“,thisDataSet.Tables“t1“.Rows0“
47、xm“);3.使用 ADO.NET 添加表中数据行。(参见 D:GZC#备课 AddRow 程序)using System;using System.Data;using System.Data.OleDb;namespace UpdatingDataclass Class1static void Main(string args)/ Specify SQL Server-specific connection stringOleDbConnection thisConnection = new OleDbConnection(“Provider=Microsoft.Jet.OLEDB.4.0
48、;Data Source=D:gzc#备课db1.mdb“);thisConnection.Open();/ Create DataAdapter object for update and other operationsOleDbDataAdapter thisAdapter = new OleDbDataAdapter( “SELECT xh, xm,XB,NL FROM t1“, thisConnection);/ Create CommandBuilder object to build SQL commandsOleDbCommandBuilder thisBuilder = ne
49、w OleDbCommandBuilder(thisAdapter);/ Create DataSet to contain related data tables, rows, and columnsDataSet thisDataSet = new DataSet();/ Fill DataSet using query defined previously for DataAdapterthisAdapter.Fill(thisDataSet, “t1“);/ Show data before changeConsole.WriteLine(“#rows before change: 0