ADO.NET是一组用于和数据源进行交互的面向对象类库。通常情况下,数据源是数据库,但它同样也能够是文本文件、Excel表格或者XML文件。
ADO.NET支持两种访问数据的模型:无连接模型和连接模型。无连接模型将数据下载到客户机,并在客户机上将数据封装到内存,然后可以像访问本地关系数据库一样访问内存中的数据,如DataSet;连接模型则依赖于逐记录的访问,这种访问要求打开并保持与数据源的链接。
Connection 类
和数据库交互,你必须连接它。连接帮助指明数据库服务器、数据库名字、用户名、密码,和连接数据库所需要的其它参数。Connection对象会被Command对象使用,这样就能够知道是在哪个数据源上面执行命令。
与数据库交互的过程意味着你必须指明想要执行的操作。这是依靠Command对象执行的。你使用Command对象来发送SQL语句给数据库。Command对象使用Connection对象来指出与哪个数据源进行连接。你能够单独使用Command对象来直接执行命令,或者将一个Command对象的引用传递给DataAdapter,它保存了一组能够操作下面描述的一组数据的命令。
Command对象
成功于数据建立连接后,就可以用Command对象来执行查询、修改、插入、删除等命令; Command对象常用的方法有ExecuteReader方法、ExecuteScalar()方法和ExecuteNonQuery()方法;插入数据可用ExecuteNonQuery()方法来执行插入命令。
DataReader类
许多数据操作要求你只是读取一串数据。DataReader对象允许你获得从Command对象的SELECT语句得到的结果。考虑性能的因素,从DataReader返回的数据都是快速的且只是“向前”的数据流。这意味着你只能按照一定的顺序从数据流中取出数据。这对于速度来说是有好处的,但是如果你需要操作数据,更好的办法是使用DataSet。
DataSet对象
DataSet对象是数据在内存中的表示形式。它包括多个DataTable对象,而DataTable包含列和行,就象一个普通的数据库中的表。你甚至能够定义表之间的关系来创建主从关系(parent-child relationships)。DataSet是在特定的场景下使用――帮助管理内存中的数据并支持对数据的断开操作的。DataSet是被所有Data Providers使用的对象,因此它并不像Data Provider一样需要特别的前缀。
DataAdapter类
某些时候你使用的数据主要是只读的,并且你很少需要将其改变至底层的数据源。同样一些情况要求在内存中缓存数据,以此来减少并不改变的数据被数据库调用的次数。DataAdapter通过断开模型来帮助你方便的完成对以上情况的处理。当在一单批次的对数据库的读写操作的持续的改变返回至数据库的时候,DataAdapter 填充(fill)DataSet对象。DataAadapter包含对连接对象以及当对数据库进行读取或者写入的时候自动的打开或者关闭连接的引用。另外,DataAdapter包含对数据的SELECT、INSERT、UPDATE和DELETE操作的Command对象引用。你将为DataSet中的每一个Table都定义DataAadapter,它将为你照顾所有与数据库的连接。所有你将做的工作是告诉DataAdapter什么时候装载或者写入到数据库。
DataTable类
DataTable 是一个数据网格控件。它可以被应用在 VB 和 ASP 上。它无须代码就可以简单的绑定数据库。它具有微软风格的用户界面。
总结
ADO.NET是与数据源交互的.NET技术。有许多的Data Providers,它将允许与不同的数据源交流――取决于它们所使用的协议或者数据库。然而无论使用什么样的Data Provider,你将使用相似的对象与数据源进行交互。SqlConnection对象管理与数据源的连接。SqlCommand对象允许你与数据源交流并发送命令给它。为了对进行快速的只“向前”地读取数据,使用SqlDataReader。如果想使用断开数据,使用DataSet并实现能进行读取或者写入数据源的SqlDataAdapter。
*********************************************************************************************************************************************
注意:下面的语言描述中,是以SQL Server为例的。我的代码是以Access为例的。
1. Connection对象
需要引入System.Data.SqlClient命名空间下的SqlConnection类
Connection对象包括四种访问数据库的对象类(数据提供程序),根据使用数据库的不同,引入不同的命名空间
- Sql Server数据提供程序,位于System.Data.SqlClient命名空间
- ODBC数据提供程序,位于System.Data.Odbc
- OLE DB 数据提供程序,位于System.Data.OleDb,Access的话可以用这个。
- Oracle数据提供程序,位于System.Data.OracleClient
通过SqlConnection对象的State属性判断数据库的连接状态,属性值为ConnectionState的枚举值:
Broken:连接中断,在连接打开后才会发生这种情况,可以关闭连接后重新打开
- Closed:关闭
- Connecting:连接中
- Executing:连接对象正在执行命令
- Fetching:连接对象正在检索数据
- Open:打开状态
关闭连接:
Close() :关闭一个连接,关闭后可直接打开 Open()
Dispose() :关闭一个连接,同时清理连接所占用的资源,关闭后不能再直接用Open方法打开连接,必须重新初始化连接后再打开。
下面是一个打开关闭Access数据库的例子:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Data.OleDb; //OleDb 提供程序
- // using System.Data.SqlClient; //.SqlServer; 提供程序
- namespace AccessTest
- {
- public partial class Form1 : Form
- {
- OleDbConnection conn;
- // SqlConnection conn;
- private void button1_Click(object sender, EventArgs e)
- {
- try
- {
- //连接字符串
- //string ConnStr = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:AccessTest围岩稳定性预测知识库.mdb; User Id=admin; Password=";
- string ConnStr = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:\AccessTest\围岩稳定性预测知识库.mdb;";
- //创建SqlConnection对象,注意因引入命名空间,访问数据库类型的不同而不同
- //conn = new SqlConnection(ConnStr);
- //创建OleDbConnection对象
- conn = new OleDbConnection(ConnStr);
- conn.Open();
- if (conn.State == ConnectionState.Open)
- {
- MessageBox.Show("数据库连接已经打开");
- }
- }
- catch
- {
- MessageBox.Show("数据库连接异常");
- }
- }
- private void button2_Click(object sender, EventArgs e)
- {
- try
- {
- conn.Close(); //关闭
- if (conn.State == ConnectionState.Closed)
- {
- MessageBox.Show("数据库连接已成功关闭");
- }
- conn.Open(); //重新打开
- if (conn.State == ConnectionState.Open)
- {
- MessageBox.Show("数据库连接已经重新打开");
- }
- }
- catch(Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
- public Form1()
- {
- InitializeComponent();
- }
- }
- }
2. Command对象
数据命令对象,用于向数据库发送SQL命令,主要有以下几种形式:
- SqlCommand:SqlServer数据库
- OleDbCommand:OLE DB打开的数据库,Access、MySQL都是OLE DB 公开的数据库
- OdbcCommand:用于向ODBC公开的数据库发送SQL语句
- OracleCommand:Oracle数据库
Command对象有三个重要属性,Connection属性、CommandText属性、CommandType属性。
- Connection属性用于设置SqlCommand对象使用的SqlConnection连接对象。
- CommandText用于设置要对数据源执行的SQL 语句或存储过程。
- CommandType用于指定CommandText的类型,是CommandType的枚举值:StoredProcedure 存储过程名称;TableDirect表名称;Text - SQL文本命令
(1)ExecuteNonQuery()方法
执行SQL语句,并返回受影响的条数。通常用于添加、删除、修改命令
(2)ExecuteReader()方法
执行SQL语句,返回一个包含数据的SqlDataReader对象的实例,select命令
(3)ExecuteScalar()
执行SQL语句,返回结果集中第一行第一列,如果为空就返回空引用。常用聚合函数一起使用
- AVG 平均值
- COUNT 统计
- MAX 最大值
- MIN 最小值
- SUM 和
- private void button3_Click(object sender, EventArgs e) //Command
- {
- try
- {
- if (conn.State == ConnectionState.Open)
- {
- OleDbCommand cmd = new OleDbCommand();
- cmd.Connection = conn;
- cmd.CommandText = "select count(*) from 李雅庄矿围岩物理力学性质";
- cmd.CommandType = CommandType.Text;
- int i = Convert.ToInt32(cmd.ExecuteScalar()); // ExecuteScalar 第一行、第一列
- MessageBox.Show("共有" + i.ToString() + "条数据");
- // ExecuteNonQuery() 方法
- cmd.CommandText = "update 李雅庄矿围岩物理力学性质 set KY = 12";
- int k = Convert.ToInt32(cmd.ExecuteNonQuery());
- MessageBox.Show(i.ToString() + "条数据受影响");
- //ExecuteReader 方法
- cmd.CommandText = "select * from 李雅庄矿围岩物理力学性质";
- OleDbDataReader oddr = cmd.ExecuteReader();
- string str = "";
- while (oddr.Read())
- {
- str += oddr[2].ToString(); //2为第几列, 0 开始
- }
- MessageBox.Show(str);
- //ExecuteScalar 方法,见上面
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
3. DataReader对象
数据读取器对象,提供只读向前的游标。如果应用程序只是需要向前读取数据,并不需要修改数据,可以使用该对象进行读取。
根据数据库的不同,有四种类型:SqlDataReader、OleDbDataReader、OdbcDataReader、OracleDataReader
(1)是否有值 HasRows属性
(2)读取数据,Read方法,游标下移。对于每个Connection只能打开一个DataReader。
- private void button4_Click(object sender, EventArgs e) //DataReader
- {
- try
- {
- OleDbCommand cmd = new OleDbCommand();
- cmd.Connection = conn;
- cmd.CommandText = "select count(*) from 李雅庄矿围岩物理力学性质";
- cmd.CommandType = CommandType.Text;
- OleDbDataReader oddr = cmd.ExecuteReader();
- if (oddr.HasRows)
- {
- MessageBox.Show("数据表中有值");
- }
- string str = "";
- while (oddr.Read())
- {
- str += oddr[2].ToString(); //2为第几列, 0 开始
- }
- MessageBox.Show(str);
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
4.DataAdapter 数据适配器
在DataSet与数据源之间起到桥梁的作用,4个属性实现与数据源的互通
- SelectCommand:向数据库发送查询语句
- DeleteCommand:删除
- InsertCommand:插入
- UpdateCommand:更新
(1)Fill 方法用于填充DataSet数据集,使用Select语句从数据源中检索数据。注意:connection对象必须有效,但不需将其打开,因为DataAdapter对象会自动打开关闭数据库。
public int Fill(DataSet dataSet, string srcTable);
dataSet:要填充的数据集
srcTable:用于表映射的源表的名称
(2)Update方法 更新数据库,将DataSet中修改的数据更新到数据库中。
在调用update方法前,要实例化一个CommandBuilder类,该类能自动根据DataAdapter的SelectCommand属性指定的SQL语句判断其它的InsertCommand、UpdateCommand和DeleteCommand,这样就不需要设置这三个属性了,而是直接使用DataAdapter的Update方法更新DataSet、DataTable、DataRow数组。
- DataSet ds ; //建立数据集
- OleDbDataAdapter odda; //适配器
- private void button5_Click(object sender, EventArgs e) //DataAdapter
- {
- try
- {
- OleDbCommand cmd = new OleDbCommand();
- cmd.Connection = conn;
- cmd.CommandText = "select * from 李雅庄矿围岩物理力学性质";
- cmd.CommandType = CommandType.Text;
- //另一种建立 command 对象的构造函数
- // OleDbCommand cmd = new OleDbCommand("select * from 李雅庄矿围岩物理力学性质",conn);
- ds = new DataSet(); //建立数据集
- odda = new OleDbDataAdapter(); //建立数据适配器
- odda.SelectCommand = cmd;
- odda.Fill(ds, "李雅庄矿围岩物理力学性质");
- dataGridView1.DataSource = ds.Tables[0];
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
- private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
- {
- //单击某条数据,显示其详细信息。
- //注意,学习 下面的写法
- try
- {
- textBox5.Text = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1].Value.ToString(); //主键
- textBox1.Text = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[4].Value.ToString(); //第几列,索引从 0 开始
- textBox2.Text = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[5].Value.ToString();
- textBox3.Text = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[6].Value.ToString();
- textBox4.Text = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[7].Value.ToString();
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
- private void button6_Click(object sender, EventArgs e) //更新
- {
- try
- {
- DataTable dt = ds.Tables["李雅庄矿围岩物理力学性质"];
- odda.FillSchema(dt, SchemaType.Mapped); //把表结构加载到“李雅庄矿围岩物理力学性质”表中
- DataRow dr = dt.Rows.Find(textBox5.Text); //创建DataRow,使用dt.Rows.Find方法时必须设置主键
- //设置DataRow的值
- dr["KY"] = textBox1.Text.Trim();
- dr["KL"] = textBox2.Text.Trim();
- dr["E"] = textBox3.Text.Trim();
- dr["U"] = textBox4.Text.Trim();
- //实例化一个CommandBuilder
- OleDbCommandBuilder odcb = new OleDbCommandBuilder(odda);
- odda.Update(dt);
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
5. DataSet对象
DataSet对象就像存放在内存中的一个小型数据库,可以包含数据表、数据列、数据行、视图、约束以及关系等。
(1)合并 MERGE
public void Merge(DataSet dataSet, bool preserveChanges, MissingSchemaAction missingScheAction);
- dataSet: 将要被合并的DataSet对象
- preserveChanges:是否保留当前DataSet的更改,true,false
- missingSchemaAction:枚举值
- Add:添加必要的列以完成架构
- AddWithKey:添加必要的列和主键信息以完成绞股,可以在DataTable上显示设置主键信息
- Error:如果缺少指定的列映射,则生成InvalidOperationException
- Ignore:忽略额外列
(2)复制 Copy
DataSet ds2 = ds1.Copy();