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());
五、 using close
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);//填充DataSet

DataRow 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接受,然后再调用DataTableRows属性的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;这两句代码,最后用SqlTransactionCommit()方法或者Rollback()对事务进行提交或者回滚

 

 

 

 

你可能感兴趣的:(.net)