ADO.NET数据操作及常用类概述
在C#语言中ADO.NET是在ADO的基础上发展起来的,ADO(Active Data Object)组件类库,用于访问数据库,而ADO.NET实在.NET平台上访问数据库的组件。ADO.NET是以ODBC(Open Database Connectivity)的方式来访问数据库的一种技术。
ADO.NET的常用命名空间如下
命名空间 | 数据提供程序 |
---|---|
System.Data.SqlClient | Microsoft SQL Server |
System.Data.Odbc | ODBC |
System.Data.OracleClient | Oracle |
System.Data.OleDb | OLE DB |
在使用ADO.NET进行数据库操作时通常会用到5个类,分别时Connection类、Command类、DataReader类、DataAdapter类、DataSet类。
在接下来的的讲解中我们将以连接SQL Server为例介绍ADO.NET中的对象,引用的命名空间为System.Data.SqlClient.
除了DataSet类以外,其他对象前面都加上了Sql,即SqlConnection,SqlCommand,SqlDataReader,SqlDataAdapter.
1.Connection类
该类主要是用于数据库中建立连接和断开连接的操作,并能通过该类获取当前数据库的连接状态。
使用Connection类根据数据库的连接字符串能连接上任意的数据库,例如SQLServer、Oracle、Mysql等。
但是在.NET平台下,由于提供了一个SQL Server数据库,并额外提供了一些操作菜单便于操作,所以推荐使用SQLServer数据库。
2.Command类
该类主要对数据库执行增加、删除、修改以及查询的操作。
通过在Command类的对象中传入不同的SQL语句,并且用相应的方法来执行SQL语句。
3.DataReader类
该类用于读取从数据库中查询出来的数据,但在读取时仅能向前读不能向后读,并且不能修改该类对象中的值。
在数据库连接中断时,该类对象中的值也随之被清除。
4.DataAdapter类
该类与DataSet联用,它主要用于将数据库的结果运送到DataSet中保存。
DataAdapter可以看作数据库与DataSet的一个桥梁,不仅可以将数据库中的操作结果运送到DataSet中,也能将更改后的DataSet保存到数据库中。
5.DataSet类
该类与DataReader类似,都用于存放数据库查询的结果。
不同的是,DataSet类中的值不仅可以重复多次读取,还可以通过改变DataSet中的值更改数据库的值。
此外,DataSet类中的值在数据库断开的情况下依然可以保留原来的值。
C# Connection:连接数据库
Connection类概述
Connection类根据要访问的数据和访问的方式不同,使用的命名空间也不同,类名也稍有区别,在这里我们使用的是SQL Connection类。以及微软提供的SQl Server 2014数据库。
SqlConnection类中提供的常用属性和方法如下表所示:
属性或方法 | 说明 |
---|---|
SqlConnection() | 无参数构造方法 |
SqlConnection(string connectionstring) | 带参数的构造方法,数据库连接字符串作为参数 |
Connectionstring | 属性,获取或设置数据库的连接字符串 |
State | 属性,获取当前数据库的状态,由枚举类型Connectionstate为其提供值 |
ConnectionTimeuot | 属性,获取在连接时终止尝试并产生错误之前的等待时间 |
DataSource | 属性,获取要连接的SQL Server的实例名 |
Open() | 方法,打开一个数据库连接 |
Close() | 方法,关闭数据库连接 |
BeginTransation() | 方法,开始一个数据库事务 |
使用SqlConnection连接数据库
在使用Connection连接SQL Server2014时,先要编写连接字符串。
数据库连接串的书写方式有很多,这里介绍最常用的两种方法。
第一种方式
server=服务器名称/数据库的实例名;uid=登录名;pud=密码;database=数据库名称
其中:
- server:用于指定要访问的数据库的数据库实例名,服务器名称可以换成IP地址或者数据库所在的计算机名称,如果访问的是本机数据库,则可以用"."来代替,如果使用的是默认的数据库实例名,则可以省略数据库实例名。例如连接的是本机的默认数据库,则可以写成"server=."
- uid:登录到指定SQL Server数据库实例的用户名,相当于SQL Server身份验证方式登录数据库时使用的用户名,例如sa用户。
- pwd:与uid对应的密码。
- database:要访问数据库实例下的数据库名。
第二种方式
Data Source=服务器名称/数据库实例;Initial Catalog=数据库名称;User ID=用户名;Password=密码
其中:
- Data Source:与第一种连接串的Server属性的写法一样,用于指定数据库所在的服务器名称和数据库实例名,如果连接的是默认的本机数据库实例名,则写成"Data Source=."的形式。
- Initial Catalog:与第一种连接串的写法的database属性一样,用于指定在Data Source中数据库实例下的数据库名。
- User ID:与第一种连接串中的uid属性的写法一样,用于指定登录数据库的用户名。
- Password:与第一种连接串中的pwd属性的写法一样,用于指定用户名对应的密码。
此外,还可以在连接字符串中使用Integrate Security = true的属性,省略用户名和密码,即以Windows身份验证的方式登录SQL Server数据库。
将数据库连接更改如下:
Data Source = 服务器名称/数据库实例名;Initial Catalog=数据库名称;Integrate Security=true
1.创建SqlConnection类的实例
对于SqlConnection类来说,上表中提供了两个构造方法,通常是使用带字符串参数的方法来设置数据库的连接串创建其实例,语句形式如下。
SqlConnection 连接对象名 = new SqlCOnnection(数据库连接串);
2.打开数据库连接
在创建SqlConnection连接类实例后并没有连接上数据库,需要使用连接类的Open()方法打开数据库的连接
在使用Open()方法打开数据库的连接时,如果数据库的连接串不正确或者数据库处于关闭状态,会出现打开数据库失败的相关异常,因此需要通过异常处理来处理异常。
打开数据库连接的语句如下。
连接对象名.Open();
3.关闭数据库连接
在对数据库操作结束后要将数据库的连接断开,以节省数据库连接的资源。
关闭数据库连接的语句如下:
连接对象名.Close();
如果打开数据库连接时使用了异常处理,则关闭数据库连接的语句放到异常处理的finally语句中,这样能保证无论是否发生了异常都将数据库的连接断开,以释放资源。
除了使用异常处理的方式释放资源,还可以使用using的方式来释放资源。具体的语句如下:
using(SqlCOnnection 连接对象名 = new SqlConnection(数据库连接串))
{
//打开数据库的连接
//对数据库相关操作的语句
}
using关键字的用法主要有两个,一个是引用命名空间,一个是创建非托管资源对象。
在.net平台上资源分为托管资源和非托管资源,托管资源是由.net框架直接提供对其资源在内存中的管理,例如声明变量;非托管资源则不能直接由.net框架对其管理,需要用代码来释放资源,例如数据库资源,操作系统资源等。
下面通过实例来演示SqlConnection类的使用
//编写数据库连接串
string connStr = "Server=.;uid=sa;pwd=sa;database=student";
//创建SqlConnection实例
SqlConnection conn = null;
try
{
conn = new SqlConnection(connStr);
//打开数据库连接
conn.Open();
MessageBox.Show("数据库连接成功");
}
catch(Exception ex)
{
MessageBox.Show("数据库连接失败"+ex.toString());
}
finally
{
if(conn != null)
{
//关闭数据库连接
conn.Close();
}
}
C# Command:操作数据库
Command类的概述
在System.Data.SqlClient 命名空间下,对应的Command对象为SqlCommand,在创建SqlCommand实例前必须已经创建了与数据库的连接。
SqlCommand类中的常用的构造方法如下。
构造方法 | 说明 |
---|---|
SqlCommand() | 无参数构造方法 |
SqlCommand(string commandText,SqlConnection conn) | 带参数的构造方法,第一个参数是执行的Sql语句,第二个参数是数据库连接对象 |
对数据库的操作不仅是对数据表的操作,还包括对数据库、视图、存储过程等数据库对象的操作,接下来主要介绍的是对数据表和存储过程的操作。
在对不同数据库对象进行操作时,SqlCommand类提供了不同的数据和方法,常用的属性和方法如下。
属性或方法 | 说明 |
---|---|
CommandText | 属性,Command对象中要执行的SQL语句 |
Connection | 属性,获取或设置数据库的连接对象 |
CommandType | 属性,获取或设置命令类型 |
Parameters | 属性,设置Command 对象中Sql语句的参数 |
ExecuteReader() | 方法,获取执行语句查询的结果 |
ExecuteScale() | 方法,返回查询结果中第一行第一列的值 |
ExecuteNonQuery() | 方法,执行对表的增加、删除、修改操作 |
使用Command 类操作数据库
Command类中提供了3种命令类型,分别是Text、TableDirect以及StoredProcedure,默认情况下是Text。
所谓的Text类型是指使用SQL语句的形式,包括增加、删除、修改以及查询的SQL语句。
StoredProcedure 用于执行存储过程,TableDirect仅在OLD DB驱动程序中生效
在使用Command类操作数据库的时候需要通过以下步骤来完成。
1.创建SqlCommand类实例
创建SqlCommand类的实例分两种情况,一种是命令类型为Text的,一种是命令类型为StoredProcedure的
//命令类型为Text
SqlCommand SqlCommand类实例名 = new SqlCommand(SQL语句,数据库连接类的实例);
其中:
- SQL语句:指该SqlCommand类的实例要执行的SQL语句
- 数据库连接类的实例:指使用SqlConnection类创建的实例,通常数据库连接类的实例处于打开状态。
//命令类型为StoredProcedure
SqlCommand SqlCommand类实例名 = new SqlCommand(存储过程名,数据库连接类的实例);
需要注意的是,存储过程必须是当前数据库实例中的存储过程,并且在调用带参数的存储过程时,还需要在SqlCommand类的实例中添加对应的存储过程参数。
为存储过程添加参数,需要使用SqlCommand类实例的Parameters属性来设置,具体代码如下
SqlCommand类实例.Parameters.Add(参数名,参数值);
在这里,参数名和存储过程中定义的参数名要一致。
2.执行对数据表的操作
在执行对数据表的操作时一般分两种情况,一种是执行非查询SQL语句的操作,即增加、修改、删除的操作,一种是执行查询SQL的操作。
执行非查询语句SQL的操作
在执行非查询SQL语句时并不需要返回表中的数据,直接使用SqlCommand 类中的 ExecuteNonQuery方法即可,该方法返回一个整数,用于返回SqlCommand类执行SQL语句后,对表中数据影响的行数。
该方法返回值为-1时,代表SQL语句执行失败,当该方法返回值是0时,代表SQL语句对当前数据表的数据没有影响。
例如:要删除学号为1100的学生信息,而表中不存在该学号学生的信息,SQL语句正常执行,但表中的影响行数为0。
具体代码如下:
SqlCommand类实例.ExecuteNonQuery();
需要注意的事,如果执行的SQL语句在数据库中执行错误,则会产生异常,因此该部分需要进行异常处理。
执行查询语句的操作
在执行查询语句时通常需要返回查询结果,SqlCommand类中提供的ExecuteReader()方法在执行查询语句之后,会返回一个SqlDataReader类型的值,通过遍历SqlDataReader类中的结果即可得到返回值。
具体代码如下:
SqlDataReader dr = SqlCommand类实例.ExecuteReader();
此外,如果在查询语句结束后不需要返回所有的查询结果,而仅需要返回一个值,例如查询表中的记录行数,这时候可以使用ExecuteScalar()方法。
int returnValue = SqlCommand类实例.ExecuteScalar();
C# DataReader:读取查询结果
DataReader:概述
DataReader类在System.Data.SqlClient命名空间中,对应的类是SqlDataReader,主要用于读取表中的查询结果,并且是以只读的方式读取的(即不能修改DataReader中存放的数据)。
正是由于DataReader类的特殊的读取方式,其访问数据的速度也比较快,占用的服务器资源比较少。
SqlDataReader类常用的属性和方法如下:
属性或方法 | 说明 |
---|---|
FileCount | 属性,获取当前行中的列数 |
HasRows | 属性,获取DataReader中是否包含数据 |
IsClosed | 属性,获取DataReader的状态是否已经被关闭 |
Read() | 方法,让DataReader对象进入到下一条数据 |
Close() | 方法,关闭DataReader对象 |
Get XXX(int i) | 方法,获取指定的列值,其中XXX代表的是数据类型。例如获取当前行第一列double类型的值,获取方法为GetDouble(0) |
使用DataReader类读取查询的结果
再使用DataReader类读取查询结果时需要注意,当查询结果仅为一条时,可以使用if语句查询DataReader对象中的数据,如果返回值是多条数据,需要通过while语句遍历DataReader对象中的数据。
再使用DataReader类读取查询结果时需要通过以下步骤完成:
1.执行SqlCommand对象中的ExecuteReader()方法
具体代码如下。
SqlDataReader dr = SqlCommand类实例.ExecuteReader();
2.遍历SqlDataReader中的结果
SqlDataReader类中提供了Read()方法用于判断其是否有值,并指向SqlDataReader结果中的下一条记录。
dr.Read()
如果返回的是true,则可以读取该条记录,否则无法读取。
在读取记录时,要根据表中数据类型来读取表中相应的列。
3.关闭SqlDataReader
下面通过实例来演示SqlDataReader类的使用
public string sqlRead(string name)
{
string msg = null;
//编写数据库连接串
string connStr = "Server=.;uid=sa;pwd=sa;database=student";
//创建SqlConnection实例
SqlConnection conn = null;
//定义SqlDataReader类
SqlDataReader dr = null;
try
{
conn = new SqlConnection(connStr);
//打开数据库连接
conn.Open();
string sql = @"select id,password, from userInfo where name = '{0}' ";
//填充SQL语句
sql = string.Formate(sql,name);
//创建SqlCommand对象
SqlCommand comm = new SqlCommand(sql,conn);
//执行SQL语句
dr = comm.ExecuteReader();
//判断执行语句是否成功
if(dr.Read())
{
//读取指定用户对应的用户和密码
msg = "用户编号"+dr[0] +"密码"+dr[1];
}
return msg;
}
catch(Exception ex)
{
return ex.Tostring();
}
finally
{
if(dr != null)
{
//关闭SqlDataReader对象
dr.Close();
}
if(conn != null)
{
//关闭数据库连接
conn.Close();
}
}
}
C# DataSet和DataTable:将查询结果保存到DataSet或DataTabel中
再执行对表中数据的查询的时还能将数据保存到DataSet中,但是需要借助DataAdapter类来实现。
在实际应用中,DataAdapter与DataSet是在查询操作中使用最多的类。
此外,还可以通过DataSet实现对表中数据的增加、修改、删除操作。
DataAdapter与DataSet类简介
DataAdapter类用于将数据表中的数据查询出来添加到DataSet中,DataAdapter在System.Data.SqlClient命名空间下对应的类名是SqlDataAdapter。
SqlDataAdapter类的主要构造方法如下标所示。
构造方法 | 说明 |
---|---|
SqlDataAdapter(SqlCommand cmd) | 带参数的构造方法,传递SqlCommand类的对象作为参数 |
SqlDataAdapter(string sql,SqlConnection conn) | 带参数的构造方法,sql参数是指定对数据表执行的SQL语句,conn是数据库连接对象 |
SqlDataAdapter() | 不带参数的构造方法 |
从SqlDataAdapter类的构造方法可以看出,SqlDataAdapter类需要与SqlCommand类和SqlConnection类一起使用
SqlDataAdapter类常用属性和方法如下表所示
属性或方法 | 说明 |
---|---|
SelectCommand | 属性,设置SqlDataAdapter中要执行的查询语句 |
insertCommand | 属性,设置SqlDataAdapter中要执行的插入语句 |
UpdateCommand | 属性,设置SqlDataAdapter中要执行的修改语句 |
DeleteCommand | 属性,设置SqlDataAdapter中要执行的删除语句 |
Fill(DataSet ds) | 方法,将SqlDataAdapter类中的查询出的结果全部填充到DataSet对象中 |
Fill(DataTable dt) | 方法,将SqlDataAdapter类中查询出的结果填充到DataTabel对象中, DataTabel是数据表对象,在DataSet对象中由多个DataTable对象构成 |
Update(DataSet ds) | 方法,更新DataSet对象中的数据 |
Update(DataTabel dt) | 方法,更新DataTable对象中的数据 |
DataSet类是一种与数据库结构相似的数据集,每个DataSet都是由若干个数据表构成的,DataTable即数据表,每个DataTable也都是由行和列构成的,行使用DataRow类表示、列使用DataColumn类表示。
此外,用户还可以通过DataRelation类来设置数据表之间的关系。
下面介绍DataSet类以及DataTabel类的使用。
DateSet类
DataSet类中的构造方法如下所示
构造方法 | 说明 |
---|---|
DataSet() | 无参数构造方法 |
DataSet(string DataSetName) | 带参数构造方法,DataSetName参数用于指定数据集名称 |
DataSet类中常用属性和方法如下所示
属性或方法 | 说明 |
---|---|
Tables | 属性,获取DataSet中所有数据表的集合,Tables[0]代表集合中第一个数据表 |
CaseSensitive | 属性,获取或设置DataSet中的字符串是否区分大小写 |
Relations | 属性,获取DataSet中包含的关系集合 |
Clear() | 方法,清空DataSet中的数据 |
Copy() | 方法,复制DataSet中的数据 |
AcceptChanges() | 方法,更新DataSet中的数据 |
HasChanges() | 方法,获取DateSet中是否有数据发生变化 |
RejectChanges() | 方法,撤销对DataSet中数据的更改 |
DataTable类
DataTabel 作为DataSet中的重要对象,其与数据表的定义是类似的,都是由行和列构成的,并有唯一的表明。
从SqlDataAdapter类的填充方法(Fill)中我们可以看出允许将数据直接填充到DataTable中,这样既能节省存储空间也能简化查找数据表中的数据。
DataTable中常用的构造方法:
构造方法 | 说明 |
---|---|
DataTable() | 无参数构造方法 |
DataTable(string TableName) | 但参数构造方法,TableName参数用于指定数据表的名字 |
DataTable与DataSet有很多相似的属性和方法,在下面列出与DataSet类属性不同的方法。
属性 | 说明 |
---|---|
TableName | 属性,获取或设置DataTable的名称 |
Columns | 属性,获取DataTable中列的集合 |
Rows | 属性,获取DataTable中行的集合 |
DataSet | 属性,获取DataTable所在的DataSet |
Constraints | 属性,获取DataTable中所有的约束 |
使用DataTable和DataSet类存放查询的结果
下面分别来演示DataSet和DataTable的使用
public DataSet getDataSet(string sql)
{
//编写数据库连接字符串
string connStr = "Server=.;uid=sa;pwd=sa;database=student";
//创建 SqlConnection对象
SqlConnection conn = null;
//创建DataSet类的对象
DataSet ds = new DataSet();
try
{
conn = new SqlConnection(connStr);
//打开数据库连接
string sql = "select name from userInfo";
//创建SqlDataAdapter类对象
SqlDataAdapter sda = new SqlDataAdapter(sql , conn);
//使用SqlDataAdapter对象sda将查询结果填充到DataSet对象ds中
sda.Fill(ds);
return ds;
}
catch(Exception ex)
{
return null;
}
finally
{
if(conn != null)
{
conn.CLose();
}
}
}
public DataTable getDataTable(string sql)
{
//编写数据库连接串
string connStr = "Server=.;uid=sa;pwd=sa;database=student";
//创建SqlConnection
SqlConnection conn = null;
//创建DataTable对象
DataTable dt = new DataTabel();
try
{
conn = new SqlConnection();
//打开数据库连接
conn.Open();
string sql = "select * from userInfo";
//创建SqlDataAdapter对象
SqlDataAdapter sda = new SqlDataAdapter();
//使用SqlDataAdapter对象sda将查询结果填充到DataTable中
sda.Fill(dt);
return dt;
}
catch(Exception ex)
{
return null;
}
finally
{
if(conn != null)
{
conn.Close();
}
}
}
DataRow和DataColumn:更新数据表
1.DataRow类
DataRow类代表数据表中的行,并允许通过该类直接对数据表进行添加,修改删除操作。
DataRow类中常用的属性和方法如下
属性或方法 | 说明 |
---|---|
Table | 属性,设置DataRow对象所创建DataTable的名称 |
RowState | 属性,获取当前行的状态(增删改查状态) |
hasErrors | 属性,获取当前行是否存在错误 |
AcceptChanges() | 方法,更新DataTable中的值 |
RejectChanges() | 方法,撤销对DataTable中值的更新 |
Delete() | 方法,标记当前的行被删除,并在执行AcceptChanges()方法后更新数据表 |
在DataRow中没用提供构造方法,需要通过DataTable中的NewRow方法来创建DataRow类对象,具体的语句如下。
DataTable dt = new DataTable();
DataRow dr = dt.NewRow();
这样,dr即为新添加的行;每行数据是由多列构成的,如果在DataTable对象中已经存在表结构,则直接使用dr[编号或列名] = 值 的形式即可为表中的列赋值。
2.DataColumn类
DataColumn类是数据表中的列对象,与数据库表的列定义一样,都可以为其设置列名以及数据类型。
DataColumn类常用的构造方法如下
构造方法 | 说明 |
---|---|
DataColumn() | 无参构造方法 |
DataColumn(string columnName) | 带参数构造方法,columnName参数代表的是列名 |
DataColumn(string columnName, Type dataType) | 带参数构造方法,columnName参数代表列名,dataType参数代表列的数据类型 |
DataColumn类提供了一些属性对DataColumn对象进行设置,常用的属性如下
属性 | 说明 |
---|---|
ColumnName | 属性,设置DataColumn对象的列名 |
DataType | 属性,设置DataColumn对象的数据类型 |
MaxLength | 属性,设置DataColumn对象值的最大长度 |
Caption | 属性,设置DataColumn对象显示时的列明,类似给表中给列设置别名 |
DefalutValue | 属性,设置DataColumn对象的默认值 |
AutoIncrement | 属性,设置DataColumn对象为自增长列,与SQL Server数据表中的标识列类似 |
AutoIncrementSeet | 属性,与AutoIncrement联用,用于设置自动增长列的初始值 |
AutoIncrementSept | 属性,与AutoIncrement联用,用于设置自动增长列每次增长的值 |
Unique | 属性,设置DataColumn对象的值是唯一的,类似于数据表的唯一约束 |
AllDBNull | 属性,设置DataColumn对象的值是否允许为空 |