你的位置:首页 > ASP.net教程

[ASP.net教程]ADO.NET 学习笔记 入门教程


本文转载自:http://www.youarebug.com/forum.php?mod=viewthread&tid=57&page=1&extra=#pid63

 

这是本人在学习ADP.NET过程中所作的笔记,可作为ADO.NET入门或者复习的教程。
 
连接字符串:
DataSource=localhost; AttchDBFilename=|DataDirectory|\Database1.mdf; InitialCatalog=UserDate; Integrated Security=True
参数说明:
Data Source表示数据源,其值为服务器地址和实例名,如果是正式版则不用加SQLEXPRESS,如果是免费版,必须加上SQLEXPRESS,即连接本机可以写成“.\ SQLEXPRESS”;
AttchDBFilename表示附加数据库,其值为附加数据库的地址,DataDirectory代表当前项目目录下的App_data目录,是数据库的默认存储路径;
Initial Catalog为数据库,其值为当前连接所要连接的数据库名称
注:如果要使用Sqlconnection对象,必须导入System.Data.Sqlclient命名空间
 
ADO.NET中的连接等资源都实现了IDisposable接口,可以使用using进行资源管理。也可以使用try……catch语句块括起来,但是using是最简单的。
代码语句:
using (SqlConnection con = new SqlConnection("Data Source=localhost;Initial Catalog=UserDate;Integrated Security=True")){    程序语句块;}

或者:

 

SqlConnection cnn = new SqlConnection();//创建SqlConnection对象的一个实例 cnn.ConnectionString = "Data Source=localhost;Initial Catalog=UserDate;Integrated Security=True";cnn.Open();

 

注:using的作用是及时的释放资源,在花括号结束的时候,程序会自动释放语句所申请的内存,以达到程序的最优。
 
一、通过SqlCommand对象执行SQL语句
SqlCommand对象可以执行SQL语句完成对数据库的增、删、改、查等数据操作。在SqlCommand类中,最主要的属性有CommandText,该属性用于接收要执行的SQL语句,例如cmd.CommandText = "INSERT INTOb1(name, company, position, shijian) VALUES(@Name, @Company, @Position,@Datetime)",除了CommandText属性,主要还有Connection属性,用来接收数据库连接,还有Transaction属性,用来接收事物。
其还有三个比较常用的方法,第一个是ExecuteNonQuery()方法,主要用来提交无查询结果的SQL语句,如UPDATE,INSERT,DELETE等语句,其返回值为数据库中被SQL语句影响的行数,第二个是ExecuteReader()方法,主要用来提交SELECT语句,返回值是一个数据流,里面是SELECT语句的查询结果,可以用SqlDataReader对象来接收,然后调用其Read()方法来逐行读出查询结果。第三个是ExexuteScalar()方法,主要也是用来提交SELECT语句,但是其返回值是查询结果的第一行第一列,所以适用于例如COUNT等聚合查询。
 
二、SQL注入与参数化查询
SQL注入是通过特殊的SQL语句非法获取数据库的内容。为了保证系统不被黑客进行SQL注入攻击,在SqlCommand执行SQL语句时,可以对提交的数据先进行参数化处理,参数化处理主要是通过SqlCommand对象的Parameters属性的Add方法来完成,参数化处理有两种方法,第一种既是在“执行Insert操作”中提到的,还有另外一种代码如下:
复制代码
cmd.CommandText = "INSERT INTO b1(name, company, position, shijian) VALUES(@Name, @Company, @Position, @Datetime)";        cmd.Parameters.Add(new SqlParameter("Name", Name.Text));        cmd.Parameters.Add(new SqlParameter("Company", Company.Text));        cmd.Parameters.Add(new SqlParameter("Position", Position.Text));        cmd.Parameters.Add(new SqlParameter("Datetime", DateTime.Parse(Datetime.Text)));        cmd.ExecuteNonQuery();
复制代码

注:以上的代码中需要注意一点,在第一种代码中,显示的对各个参数的数据进行了定义,但是在上面这种代码中,并未对参数进行数据定义,所以需要在提供数据时对数据进行适时的转换,例如“shijian”在数据库中定义为DateTime类型,但是其在文本框中获得的为string类型,所以需要调用DateTime的Parse方法对数据进行转换,如果数据库中的数据是int型,在赋值时也应进行相应的转换。
 
三、执行Insert操作
首先,需要申明一个SqlCommand对象;
其次,用SqlConnection的CreateCommand()函数,创建一个SqlCommand对象,然后将所要执行的SQL语句赋值给SqlCommand的CommandText属性;
最后,调用SqlCommand类的ExexuteNonQuery()方法,执行CommandText的SQL语句。
代码语句:
using(SqlCommand cmd = con.CreateComand()){    cmd.CommandText = “INSERT INTO b1(name, company, position) VALUES(“whh”, “UVGE”, “coder”)”;cmm.ExecuteNonQuery();}

或者:

 

复制代码
using(SqlCommand cmd = con.CreateComand()){       //设置SQL语句    cmm.CommandText = "INSERT INTO b1(name, company, position, shijian) VALUES(@Name, @Company, @Position, @Datetime)";    //创建参数,并定义其数据类型,要和数据库中对应的字段保持相同    cmm.Parameters.Add("@Name", SqlDbType.NVarChar);    cmm.Parameters.Add("@Company", SqlDbType.NVarChar);    cmm.Parameters.Add("@Position", SqlDbType.NVarChar);    cmm.Parameters.Add("@Datetime", SqlDbType.DateTime);    //设置参数的值,这些值来自前段的输入信息    cmm.Parameters["@Name"].Value = Name.Text;    cmm.Parameters["@Company"].Value = Company.Text;    cmm.Parameters["@Position"].Value = Position.Text;    cmm.Parameters["@Datetime"].Value = Datetime.Text;    //执行SQL语句    cmm.ExecuteNonQuery();}
复制代码

 

注:
SqlCommand类的ExecuteNonQuery()方法的返回值是当前执行的SQL语句影响的行数
 
四、执行select语句
首先,申明SqlCommand对象
其次,用SqlConnection的CreateCommand()函数,创建一个SqlCommand对象,然后将所要执行的SQL语句赋值给SqlCommand的CommandText属性;
第三,调用SqlCommand类的ExecuteReader ()方法,执行CommandText的SQL语句。
第四,申明SqlDataReader对象,并用其承接ExecuteReader ()方法所返回的数据流;
第五,用SqlDataReader类的Read()方法逐行读取数据流中的逐句,取出其中所需要字段的数据进行处理
代码语句:
复制代码
using(SqlCommand cmd = con.CreateComand()){    Cmd.CommandText = “SELECT语句”;    using(SqlDataReader reader = cmd.ExecuteReader()){While(reader.Read()){        String name = reader.GetString(reader.GetOrdinal(“name”));        //数据处理语句块;    }}}
复制代码

或者:

复制代码
using(SqlCommand cmd = con.CreateComand()){    using(SqlDataReader reader = cmd.ExecuteReader()){While(reader.Read()){        String name = reader.[“name”].ToString();        //数据处理语句块;}}}
复制代码

注:
1、User是SQL SERVER的关键字,在表名中应尽量避免,如果必须是User表,可以用SELECT * FROM [User]这样的语句来查询该表的内容
2、SqlCommand 类的ExecuteScalar()方法返回的是查询结果的第一行第一列的数据
3、在插入数据的同时想要获得当前插入数据的id(主键)号,可以通过output语法和ExecuteScalar方法实现,这是在SQLSERVER 2005以后的版本中都有的,具体语法如下:
cmd.CommandText = “INSERT INTO T_Users(UserName,PassWord) OUTPUT inserted.Id Values(“admin”, “123456”)”;int id = Convert.ToInt32(cmd.ExecuteScalar());

五、usingclose
using对实现了IDisposable接口的类进行了资源管理,只要在其作用域内using就会自动进行资源管理,当程序执行出了其作用范围,程序会自动close和dispose资源,保证资源的及时释放和回收。而Close只是关闭了当前的连接或者资源,只要其后没有dispose,还可以继续open连接,即close并未释放资源,只做了关闭处理,当close和dispose连用时,和using作用相同,但考虑到异常处理等情况,所以最好使用using,少用close和dispose。
 
六、通过数据集操作数据
数据集是最常用的访问数据的方式,其主要流程是连接数据库、进行数据查询、将查询结果填充到数据集、对数据集中的数据进行展示和操作、将操作后的数据集提交数据库,通过这一系列操作实现对数据库的修改,此过程主要通过DataSet、DataAdapter、DataTable、DataRow、DataColumn、SqlCommandBuilder等类实现。
根据上面所说到过程,逐步分析:
1、数据查询,这里的数据查询不再是通过Command对象实现,而是通过DataAdapter类的实例来实现,具体代码如下:
SqlDataAdapter sqldadp = new SqlDataAdapter("SELECT name, company, position, shijian FROM [UserDate].[dbo].[b1] WHERE shijian > '2010-01-21'", con)

上面的代码里面的con是SqlConnection对象的实例,即数据库链接
2、将数据填充到数据集,数据集也就是DataSet对象的实例了,代码如下:
DataSet order_daset = new DataSet();//创建DataSet对象实例sqldadp.Fill(order_daset);//填充DataSet对象

注意填充语句中的参数以及方法,是用SqlDataAdapter对象的实例来填充DataSet对象的实例
3、对数据集中的数据进行展示和操作,这步也是这项技术中最重要、最麻烦的一步,主要是通过DataTable对象的实例对数据进行展示和修改,而DataTable类具有很多的属性和方法,常用的属性有:Columns能够得到数据集中的字段的数据类型、大小、字段名等信息,DataSet能够获得当前DataTable实例所属的数据集,Rows可以通过下标及字段名(类似于二维数组)的方式获得指定行列的数据,常用的方法有:NewRow()方法能够创建一个空白行,可以在添加数据的时候使用,AcceptChanges()方法能够将数据表中修改提交给数据库,Clear()方法可以清楚DataTable对象中的所有数据。具体代码如下:
复制代码
DataTable dt = new DataTable();//创建数据表对象dt = order_daset.Tables[0];//填充数据表Response.Write("<table border='1'><tr><th>姓名</th><th>公司</th><th>职位</th><th>入职时间</th></tr>");for (int i = 0; i < dt.Rows.Count; i++){  //按照字段,逐行取出数据表中的内容并显示在页面上  Response.Write("<tr>");  Response.Write("<td>"+dt.Rows[i]["name"].ToString()+"</td>");  Response.Write("<td>"+dt.Rows[i]["company"].ToString()+"</td>");  Response.Write("<td>"+dt.Rows[i]["position"].ToString()+"</td>"); Response.Write("<td>"+DateTime.Parse(dt.Rows[i]["shijian"].ToString()).ToString("yyyy-MM-dd") + "</td>");  Response.Write("</tr>");}Response.Write("</table>");
复制代码

注:上面的代码主要是数据集的展示功能,需要注意的是填充数据表的语句,是由DataSet对象的Tables属性的下标为0的数据表填充的,这点是非常重要的。
下面来看看对数据集的修改并且提交数据库,对数据集的修改,可以通过DataRow以及SqlCommandBuilder对象的实例来实现,SqlCommandBuilder的作用是根据DataAdapter对象自动生成INSERT、UPDATE、DELETE语句,从而使DataAdapter对象更新数据库内容。具体代码如下:

 

复制代码
//创建DataAdapter对象实例SqlDataAdapter sqldadp = new SqlDataAdapter("SELECT name, company, position, shijian FROM [UserDate].[dbo].[b1]", con);SqlCommandBuilder scb = new SqlCommandBuilder(sqldadp);//生成插入、删除、更新语句DataSet ds = new DataSet();//创建DataSet对象sqldadp.Fill(ds);//填充DataSetDataRow Myrow = ds.Tables[0].NewRow();//在数据表中创建新的空白记录对象//从前台页面接受要插入的数据Myrow["name"] = Name.Text;Myrow["company"] = Company.Text;Myrow["position"] = Position.Text;Myrow["shijian"] = Datetime.Text;//将接收到的数据添加到DataTable中ds.Tables[0].Rows.Add(Myrow);//更新数据库中的内容sqldadp.Update(ds);Response.Write("添加成功!<br>");
复制代码

 

注:上面的代码中最关键的一个方法是SqlDataAdapter对象的Update()方法,这个方法的作用是将对数据集所作的改变提交给数据库,这部分代码与上面的展示代码所不同的是DataRow对象的实例所接收的是DataTable中的一行,而不是整个DataTable,其代码为:DataRow Myrow =ds.Tables[0].NewRow(),这句话就是说在原有的DataTable的基础上创建一个新的空行,而下面的代码则是为这个空行赋值并提交更新,同样的,如果是更新数据的话,也是获得DataTable的某一行后,然后对其中的数据进行赋值修改,然后提交,如果是删除操作,则是通过DataTable获取某行后,用DataRow接受,然后再调用DataTable的Rows属性的Remove方法删除,具体如下代码:

 

DataTable dt = ds.Tables[0];dt.Rows.Remove(Myrow);

 

七、网络数据的事务处理
事务处理是为了防止在网络上多用户对数据库的并发操作破坏数据的一致性和完整性,而事务处理主要通过SqlTransaction对象完成,其主要的方法有:Commit()方法主要负责提交事务处理完成真正的数据库查询更新操作,Rollback()方法主要负责当数据查询更新等数据库操作出现异常时的事务回滚。ADO.NET的事务处理主要通过SqlCommand对象来实现事务对象,代码如下:
复制代码
using (SqlConnection con = new SqlConnection("Data Source = localhost; Initial Catalog = UserDate; Integrated Security = True"))    {  SqlTransaction transql = null;//申明SqlTransaction对象的实例  SqlCommand cmd = new SqlCommand();  try  {    con.Open();//创建数据库链接    transql = con.BeginTransaction();//开始事务处理    cmd.Connection = con;//设置Command对象的链接    cmd.Transaction = transql;//设置Command对象的事务    //设置带参数的SQL语句    cmd.CommandText = "INSERT INTO b1(name, company, position, shijian) VALUES(@Name, @Company, @Position, @Datetime)";    //为参数赋值(注意参数在数据库中的数据类型)    cmd.Parameters.Add(new SqlParameter("Name", Name.Text));    cmd.Parameters.Add(new SqlParameter("Company", Company.Text));    cmd.Parameters.Add(new SqlParameter("Position", Position.Text));    cmd.Parameters.Add(new SqlParameter("Datetime", DateTime.Parse(Datetime.Text)));//注意数据类型转换    //执行SQL语句    cmd.ExecuteNonQuery();    //提交事务    transql.Commit();    Response.Write("添加成功!<br>");  }  catch  {    //如果程序抛出异常则做事务回滚    transql.Rollback();  }}
复制代码

注:在上面的代码中,特别要注意SqlTransaction的实例接收的是SqlConnection实例的BeginTransaction()的返回值,SqlCommand的实例的Transaction属性接收的是SqlTransaction的实例,即SqlConnection实例的BeginTransaction()的返回值,而整个事务的过程是由SqlCommand实例来书写的,也就是说,在SqlCommand实例里面的代码相对应的事务都由SqlTransaction的实例自动生成,前提是必须要有transql = con.BeginTransaction();cmd.Transaction= transql;这两句代码,最后用SqlTransaction的Commit()方法或者Rollback()对事务进行提交或者回滚