C# 第八篇 数据访问技术(一)基础入门
要使用C#进行编程,必需学习ADO.NET,因为使用ADO.NET可以非常方便地操作各种主流数据库。大部分应用程序都是使用数据库存储数据的。通过使用ADO.NET,既可以根据指定条件查询数据库中的数据,也可以对数据库中的数据进行増加、删除、修改等操作。
一、ADO.NET 概述
AD0.NET是微软.NfeT数据库的访问架构,它是数据库应用程序和数据源之间沟通的桥梁。AD0.NET主要提供面向对象的数据访问架构,该架构用来开发数据库应用程序。
1.1 ADO.NET 对象模型
AD0.NET 主要包括 Connection、Command、DataReader、DataAdapter、DataSet 和 DataTable等6个对象。
1.1 Connection对象主要用于提供与数据库的连接。
1.2 Command对象用于返回数据、修改数据、运行存储过程,以及发送或检索参数信息的数据库命令。
1.3 DataReader对象通过Command对象提供从数据库检索信息的功能。它以只读的、向前的、快速的方式访问数据库。
1.4 DataAdapter对象提供连接DataSet对象和数据源的功能。它主要使用Command对象在数据源中执行SQL命令,以将数据加载到DataSet数据集中,并确保DataSet数据集中数据的更改与数据源保持一致。 ,
1.5 DataSet对象是ADO.NET的核心。它是支持ADO.NET断开式数据方案、分布式数据方案的核心对象。DataSet对象是一个数据库容器,可以把它看作存在于内存中的数据库。无论数据源是什么,它都会提供一致的关系编程模型。
1.6 DataTable对象表示内存中数据的表。
使用ADO.NET操作数据库的步骤如图所示:
1.2 数据库访问命名空间
在.NET中,用于数据访问的命名空间如下:
<1>System.Data:提供对ADO.NET结构的类的访问。它通过ADO.NET可以生成一些组件,用于有效管理多个数据源的数据。
<2>System.Data.Common:包含由各种.NET Framework数据提供程序共享的类。
<3>System.Data.Odbc:为ODBC.NET Framework数据提供程序,描述用于访问托管空间中的ODBC数据源的类集合。
<4> System.Data.01eDb:为OLE DB.NET Framework数据提供程序,描述用于访问托管空间中的OLE DB数据源的类集合。
<5>System.Data.SqlCIient:为SQL Server.NET Framework数据提供程序,描述用于在托管空间中访问SQL Server数据库的类集合。
<6>System.Data.SqlTypes:提供SQL Server中本机数据类型的类。SqlTypes中的每个数据类型在SQLServer中具有与其等效的数据类型。
<7>System.Data.OracleClient:为Oracle的.NET Framework数据提供程序,描述用于在托管空间中访问Oracle数据源的类集合。
二、Connection 对象
所有对数据库的访问操作都是从建立数据库连接开始的。在打开数据库之前,必须先设置好连接字符串(Connectionstring),然后再调用Open方法打开连接,之后便可对数据库进行访问,最后调用Close方法关闭连接。
2.1 熟悉Connection 对象
Connection对象提供一些方法允许程序员与数据源建立连接或断开连接,例如:Oracle(System.Data.OracleClient)、SQL Server(System.Data.SqlCIient)、ODBC(System.Data.Odbc)等。
2.2 数据库连接字符串
为了让连接对象知道将要访问的数据库文件在哪里,用户必须将这些信息用一个字符串加以描述。数据库连接字符串需要提供的必要信息包括服务器名称、数据库名称和数据库的身份验证方式(Windows集成身份验证或SQL Server身份验证)。
参数 | 说明 |
Provider | 设置或返回连接提供程序的名称,仅用于OleDbConnection对象 |
Connection Timeout | 在终止尝试并产生异常前,等待连接到服务器的连接时间长度(s),默认15秒 |
Initial Catalog 或 Database | 数据库名称 |
Data Source 或 Server | 连接打开时使用的SQL Server 服务签名,或者数据库文件名 |
Password 或 pwd | SQL Server 账户的登录密码 |
User ID 或 uid | SQL Server 登录账户 |
Intergrated Security | 此参数决定连接的安全性,可能的值有True、False和SSPI(SSPI 是Ture的同义词) |
以上参数不区分大小写
下面分别以连接SQL Server数据库和连接Access数据库为例介绍如何定义数据库连接字符串。
//连接SQL Server 数据库 //string sql= "server=服务器名;user id= 用户;pwd = 密码;database = 数据库名称"; string sql= "server=xiaoke;user id= sa;pwd = 123;database = db_ems"; //连接Access数据库 //string sql ="provide=提供者; data Soure = ACCESS文件路径"; //2003以下版本 string sql ="provide=Microsoft.Jet.OLEDB.4.0; data Soure = c:\\db_ems.mdb"; //2007以下版本 string sql ="provide=Microsoft.ACE.OLEDB.12.0; data Soure = c:\\db_ems.mdb";
2.3 应用SqlConnection对象连接数据库
调用Connection对象的Open方法或Close方法可以打开或关闭数据库连接。必须在设置好数据库连接字符串后才可以调用Open方法,否则Connection对象不知道要与哪一个数据库建立连接。
以下示例执行在前置条件均已达标的情况下:
//数据库连接字符串Oracle string connString = "DATA SOURCE=实例名;PERSIST SECURITY INFO=True;USER ID=sa;password=123"; //新建连接对象conn OracleConnection conn = new OracleConnection(connString); //使用OPEN方法连接数据库 conn.Open(); //根据连接状态判断数据库是否连接成功 if(conn.State == ConnectionState.open) { Console.WriteLine("连接成功!" + conn.State.ToString()); } //使用Close方法关闭数据库 conn.Close(); //根据连接状态判断数据库是否连接成功 if(conn.State == ConnectionState.Closed) { Console.WriteLine("连接关闭成功!"); }
三、Command 对象
当使用Connection对象与数据源建立连接后,可以使用Command对象对数据源执行查询、添加、删除和修改等各种操作。操作的实现可以使用SQL语句,也可以使用存储过程。根据.NETFramework数据提供程序的不同,Command对象可以分成4种,分别是SqlCommand、
OleDbCommand、OdbcCommand和OracleCommand。
Command 对象的常用属性及说明如表
属性 | 说明 |
CommandType | 获取或设置Command对象要执行命令的类型 |
CommandText | 获取或设置要对数据源执行的SQL语句、存储过程名或表名 |
CommandTimeOut | 获取或设置在终止对执行命令的尝试并生成错误之前的等待时间 |
Connection | 获取或设置Command对象使用的Connection对象的名称 |
Parameters | 获取Command对象需要使用的参数集合 |
Command 对象的常用方法及说明
属性 | 说明 |
ExecuteNonQuery | 用于执行非SELECT命令(如INSERT命令、DELETE命令或UPDATE命令)并返回命令所影响的数据行数;也可以用来执行一些数据定义命令,比如新建、更新、删除数据库对象(如表、索引等) |
ExecuteScalar | 用于执行SELECT査询命令,返回数据中第一行第一列的值.该方法通常用来执行使用了COUNT函数(或SUM函数)的SELECT命令 |
ExecuteReader | 执行SELECT命令,并返回一个DataReader对象。这个DataReader对象是一个只读向前的数据集 |
3.1 使用Command对象操作数据
在向数据库中添加记录时首先创建SqlConnection对象连接数据库,然后定义添加数据的SQL字符串,最后调用SqlCommand对象的ExecuteNonQuery方法执行数据的添加操作。
//数据库连接信息 OracleConnection conn = new OracleConnection("DATA SOURCE=数据库实例名;PERSIST SECURITY INFO=True;USER ID=sa;password=123"); //sql语句 string strsql = "insert into cs_table(name,sex) values('小李','男')"; //执行SQL语句 OracleCommand comm = new OracleCommand(strsql, conn); //判断数据库连接状态 if (conn.State == System.Data.ConnectionState.Closed) { conn.Open(); } //判断语句是否执行成功,大于0执行成功,否则失败 if (Convert.ToInt32(comm.ExecuteNonQuery())>0) { Console.WriteLine("添加成功"); Console.ReadLine(); } else { Console.WriteLine("添加失败"); Console.ReadLine(); } //数据库连接关闭 conn.Close();
3.2 使用Command对象调用存储过程
存储过程可以使管理数据库和显示数据库信息等操作变得非常容易,它是SQL语句和可选控制流语句的预编译集合。存储过程存储在数据库内,在程序中可以通过Command对象来对其进行调用。存储过程的执行速度比SQL语句快,同时还可以保证数据的安全性和完整性。
示例代码:调用存储过程执行数据添加操作
//数据库连接信息 OracleConnection conn = new OracleConnection("DATA SOURCE=lftxt;PERSIST SECURITY INFO=True;USER ID=lftxt;password=lf152692"); // OracleCommand comm = new OracleCommand(); comm.Connection = conn; comm.CommandType = System.Data.CommandType.StoredProcedure; comm.CommandText = "cs_proc_add"; comm.Parameters.Add("@p_name",OracleDbType.Varchar2,20).Value = "小王"; comm.Parameters.Add("@p_sex", OracleDbType.Varchar2,20).Value = "女"; //判断数据库连接状态 if (conn.State == System.Data.ConnectionState.Closed) { conn.Open(); } //判断语句是否执行成功,大于0执行成功,否则失败 if (Convert.ToInt32(comm.ExecuteNonQuery())>0) { Console.WriteLine("添加成功"); Console.ReadLine(); } else { Console.WriteLine("添加失败"+ Convert.ToInt32(comm.ExecuteNonQuery())); Console.ReadLine(); } //数据库连接关闭 conn.Close();
上述示例调用的存储过程:
create or replace procedure cs_proc_add(p_name in varchar2,p_sex in varchar2) Is begin insert into CS_table (name, sex) values (p_name, p_sex); end cs_proc_add;
四、DataReader 对象
DataReader对象是一个简单的数据集,主要用于从数据源中读取只读的数据集,其常用于检索大量数据。
DataReader对象可以分为SqlDataReader对象、OleDbDataReader 对象、OdbcDataReader 对象和 OracleDataReader 对象 4 类。
由于DataReader对象每次只能在内存中保留一行,所以使用它的系统开销非常小。
在使用DataReader对象读取数据时,必须一直保持与数据库的连接,因此读取过程也被称为连线模式。
可以通过Command对象的ExecuteReader方法从数据源中检索数据来创建DataReader对象。DataReader对象常用属性及说明如表:
属性 | 说明 |
HasRows | 判断数据库中是否有数据 |
FieldCount | 获取当前行的列数 |
RecordsAffected | 获取执行SQL语句更改、添加或删除的行数 |
DataReader对象常用方法及说明如表:
方法 | 说明 |
Read | 使DataReader对象前进到下一条记录 |
Close | 关闭DataReader对 |
Get | 用来读取数据集的当前行的某一列的数据 |
4.1使用DataReader对象检索数据
在使用DataReader对象读取数据时,首先需要使用其HasRows属性判断是否有数据可供读取,如果有数据,返回True;否则返回Falseo然后使用DataReader对象的Read方法来循环读取数据表中的数据。最后通过访问DataReader对象的列索引来获取读取到的值。
string connsql = "DATA SOURCE=CXPS;PERSIST SECURITY INFO=True;USER ID=sa;password=123;"; //设置数据库连接对象 OracleConnection cxps_conn = new OracleConnection(connsql); //判断连接是否关闭 if (cxps_conn.State == ConnectionState.Closed) { //打开数据库连接 cxps_conn.Open(); } //生成DataReader OracleDataReader datareader = command.ExecuteReader(); //判断OracleDataReader对象中是否有数据 if (datareader .HasRows) { //循环读取OracleDataReader对象中的数据 while (datareader .Read()) { //显示读取的详细信息 richTextBox1.Text += "" + datareader["ID"] + " " + datareader["Name"] + " " + datareader["Money"] + "\n"; } } //关闭OracleDataReader对象 datareader.Close(); //关闭数据库连接 cxps_conn.Close();
五、DataSet 对象和 DataAdapter 对象
DataSet对象是创建在内存中的集合对象,包含任意数量的数据表及所有表的约束、索引和关系等。一个DataSet对象包含一组DataTable对象和一组DataRelation对象,每个DataTable对象都由集合对象DataColumn、DataRow和Constraint组成。
5.1 DataAdapter 对象
DataAdapter对象(数据适配器)是一种用来连接DataSet对象与实际数据源的对象。DataAdapter属性如下表:
属性 | 说明 |
SelectCommand | 获取或设置用于在数据源中选择记录的命令 |
InsertCommand | 获取或设置用于将新记录插入到数据源中的命令 |
UpdateCommand | 获取或设置用于更新数据源中记录的命令 |
DeleteCommand | 获取或设置用于从数据集中删除记录的命令 |
在.NET Framework 中使用 4 种 DataAdapter 对象,即 OleDbDataAdapter 对象、SqlDataAdapter 对象sODBCDataAdapter 对象和 OracleDataAdapter 对象。
DataSet对象是一个非连接的对象,与数据源无关,也就是说该对象并不能直接与数据源产生联系。而DataAdapter对象则负责填充DataSet对象并将其数据提交给一个特定的数据源。
DataAdapter对象与DataSet对象配合使用,可以执行数据查询、添加、修改和删除等操作。
方法 | 说明 |
Fill | 从数据源中提取数据以填充数据集 |
Update | 更新数据源 |
5.2 使用DataAdapter对象填充DataSet数据集
在使用DataAdapter对象填充DataSet数据集时,需要使用其Fill方法。该方法常用的3种形式,如下:
<1> int Fill(DataSet dataset):添加或更新参数所指定的DataSet数据集,返回值是影响的行数。
<2> int Fill(DataTable datatable):将数据填充到一个数据表中。
<3> int FiII(DataSet dataset, String tableName):填充指定的 DataSet 数据集中的指定表。
示例代码:
string connsql = "DATA SOURCE=CXPS;PERSIST SECURITY INFO=True;USER ID=sa;password=123;"; OracleConnection cxps_conn = new OracleConnection(connsql); //判断连接是否关闭 if (cxps_conn.State == ConnectionState.Closed) { //打开数据库连接 cxps_conn.Open(); } //创建OracleDataAdapter对象 sqldataada OracleDataAdapter sqldataada = new OracleDataAdapter(sSQL, cxps_conn); //创建dataset对象 DataSet ds = new DataSet(); //填充OracleDataAdapter对象的数据源至DataSet对象; sqldataada.Fill(ds); //关闭数据库连接 cxps_conn.Close();
以上代码使用了方式一,也可用以下代码替换
sqldataada.Fill(ds,"表格名称");
或者
//创建datatable对象,并赋值一个表格数据 DataTable dtable = sqldataada.Tables[0]; 创建新的dataset对象 DataSet ds_1 = new DataSet(); //创建OracleDataAdapter对象 OracleDataAdapter oracle_data_adapter = new OracleDataAdapter(sSQL, cxps_conn); //复制新的dataset对象,可是dataset对象或datatable对象 oracle_data_adapter.Fill(ds_1); 或者 oracle_data_adapter.Fill(dtable);
5.3 dataset对象使用指南
<1> 获取dataset表数据
//获取dataset对象第一个表数据 ds.Tables[0]; ds.Tables["表格名称"];
<2>获取数据表行数据
//创建行对象,并获取datable表指定行数据 DataRow row = datatable.Rows[0];
<3>获取列数据
//获取指定行的列数据 row["列名"]; row[0];
<4>其他方法
ds.Tables[0].Row[0];
<5>遍历datatable所有行数据
//这里使用了数据库连接类库,省略不少 DataSet ds = hisconn.GetDataSet(sql); //创建datatable对象 DataTable dtable = ds.Tables[0]; //创建datarow行对象从0遍历至datatable行数为止 foreach (DataRow row in dtable.Rows) { //执行语句块 }
拓展:数据库连接类库代码
DataConfig.zip
六、DataGridView 控件的使用
DataGridView控件又称为数据表格控件,它提供一种强大而灵活的、以表格形式显示数据的方式。将数据绑定到DataGridView控件的方法非常简单,在大多数情况下,只需要设置DataSource属性即可。
DataGridView控件的常用属性及说明如下:
属性 | 说明 |
Columns | 获取一个包含控件中所有列的集合 |
CurrentCell | 获取或设置当前处于活动状态的单元格 |
CurrentRow | 获取包含当前单元格的行 |
DataSource | 获取或设置DataGridView所显示数据的数据源 |
RowCount | 获取或设置DataGridView中显示的行数 |
Rows | 获取一个集合,该集合包含DataGridView控件中的所有行 |
DataGridView控件的常用事件及说明如下:
事件 | 说明 |
CellClick | 在单元格的任何部分被单击时发生 |
CellDoubleClick | 在用户双击单元格中的任何位置时发生 |
示例代码:
//为dataGridViewl设置数据源 dataGridViewl.DataSource = ds.Tables[0];