代码改变世界

ADO.NET 之 三 2

2012-12-31 19:33  y-z-f  阅读(388)  评论(2编辑  收藏  举报

 

我们接着上面的章节继续学习 SqlCommand 更高级的话题

1. 异步执行T-SQL

注意:T-SQL 语句中必须要有: Asynchronous Processing=true;

    1.1 异步执行无结果集(无参数)

          相关的方法

  •         BeginExecuteNonQuery()
  •         EndExecuteNonQuery()

          相关的类

  •          IAsyncResult

     使用方法:

 首先按照正常建立数据库连接的方式建立连接,然后创建SqlCommand实例

构造所需执行的T-SQL语句.

然后最重要的一步就是:(假设 cmd 为 SqlCommand 实例)

1 IAsyncResult result = cmd.BeginExecuteNonQuery();

其中 resultIAsyncResult 类型,用于后面用来检测该T-SQL是否执行完毕,然后调用
EndExecuteNonQuery() 来结束.否则期间不能再使用该 SqlCommand 实例执行其他任何操作

对应的关闭方法:

cmd.EndExecuteNonQuery();

但是根据MSDN文档的说,如果该异步操作尚未执行完毕就使用该方法,会导致 SqlCommand 对象在命令执行完之前一直被阻止.

并且该方法还将会返回受影响的行

以下为例子(采用NORTHWIND举例

 1 using( SqlConnection con = new SqlConnection() )
 2 {
 3     ConnectionStringSettings cssc = ConfigurationManager.ConnectionStrings["NorthWind"];//采用配置文件存储数据库连接字符串
 4    if( cssc != null )
 5     {
 6           con.ConnectionString = cssc.ConnectionString;
 7           con.Open();
 8           SqlCommand cmd = con.CreateCommand();
 9           cmd.CommandText = "SELECT * FROM Customers";
10           IAsyncResult result = cmd.BeginExecuteNonQuery();//开始异步执行
11           while( result.IsCompleted ) //确定是否已经执行完毕
12          {
13                 System.Threading.Thread.Sleep(100);
14          }
15          cmd.EndExecuteNonQuery(result);//执行完毕结束
16     }
17 }

      

      1.2 异步执行无结果集 (有参数)

         相关方法

  •         BeginExecuteNonQuery(
                          AsyncCallback callback,
                          Object stateObject
             )

   callback : 命令执行完毕后调用的 AsyncCallback 委托

   stateObject : 传递到回调过程的用户定义的状态对象(简单点就是将这个参数一并传递到上面的委托中

这里既然是通过调用委托来实现异步的所以我们要先写出被调用的委托:

1 private void CmdCallback( IAsyncResult result )
2 {
3        SqlCommand cmd = (SqlCommand)result.AsyncState;
4        int rows = cmd.EndExecuteNonQuery(result);
5 }

ps:不要和我说不知道委托是什么 -.-

这里需要说明的是  为什么 我把 result 中的 AsyncState 强行转换成 SqlCommand

这个不是固定的,我之前说过在 BeginExecuteNonQuery 中的第二参数会传递到委托,

当然学会 MFC 的可能会以为回调函数的参数中会存在,但是却不是.而是存在 result

AsyncState 中 因为是Object 类型所以我们要强行格式化.

最后当然是 EndExecuteNonQuery 操作了.不然需要使用 SqlCommand 对象的操作

是无法执行的.

 

下面是我们的主程序:

1 using( SqlConnection con = new SqlConnection() )
2 {
3       con.ConnectionString = cssc.ConnectionString;
4       con.Open();
5       SqlCommand cmd = con.CreateCommand();
6       cmd.CommandText = "DELETE TOP 1 FROM Customers";
7       cmd.BeginExecuteNonQuery(new AsyncCallback(CmdCallback),cmd);//这样这边就使用了异步
8 }


一看就知道了,第一个参数是我们之前写的回调函数,在这里传递进去了,而回调函数中我们为什么把

AsyncState 强行格式化为 SqlCommand 这里也有了解释,因为我们传递进去了一个 SqlCommand 类型的对象

Ps :可能大家会有人在回调函数中下断点,但是命中率可能很低,建议在 BeginExecuteNonQuery 下断点然后 F10 走下去(因为是本地而且操作不大所以无法体现异步)

 

     1.3 异步执行有结果集(无参数)

            相关方法

  •           BeginExecuteReader()
  •           EndExecuteReader()

     BeginExecuteReader() : 开始使用异步方式执行T-SQL语句或存储过程

     EndExecuteReader() : 获得异步执行之后得到的记录集

    其中 BeginExecuteReader() 还具有重载: BeginExecuteReader( CommandBehavior behavior ) 其中 behavior 上节已经介绍.

    我们开始使用它来,首先建立到数据库的连接这些都可以不用重复了,

    然后就是输入查询T-SQL语句,

    下面(假设 cmd 为 SqlCommand 类型的实例):

1 IAsyncResult result = cmd.BeginExecuteReader();

    最后当然关闭并且获得我们需要的记录集

1 SqlDataReader reader = cmd.EndExecuteReader(result);

   到这里我们就获得了我们需要的记录集,关于很多的细节其实和BeginExecuteNonQuery基本一致.

以 NORTHWND 举例:

 1 using( SqlConnection con = new SqlConnection() )
 2 {
 3      ConnectionStringSettings cssc = ConfigurationManager.ConnectionStrings["NorthWind"];
 4      if( cssc != null )
 5      {
 6            con.ConnectionString = cssc.ConnectionString;
 7            con.Open();
 8            SqlCommand cmd = con.CreateCommand();
 9            cmd.CommandText = "SELECT * FROM Customers";
10            IAsyncResult result = cmd.BeginExecuteReader();//开始执行异步
11            while( result.IsCompleted ) //判断是否已经执行完毕
12           {
13                   System.Threading.Thread.Sleep(100);
14           }
15           SqlDataReader reader = cmd.EndExecuteReader(result);//关闭异步并获得记录集
16           if( reader.HasRows ) //判断是否存在数据
17          {
18                int rows = reader.FieldCount;
19          }
20      }
21 }


    1.4 异步执行有结果集 (有参数)

     此方法很多和 BeginExecuteNonQuery 类似,所以直接上实例代码:

    

 1 using( SqlConnection con = new SqlConnection() )
 2 {
 3     ConnectionStringSettings cssc = ConfigurationManger.ConnectionStrings["NorthWind"];
 4     if( cssc != null )
 5     {
 6           con.ConnectionString = cssc.ConnectionString;
 7           con.Open();
 8           SqlCommand cmd = con.CreateCommand();
 9           cmd.CommandText = "SELECT * FROM Customers";
10           cmd.BeginExecuteReader(new AsyncCallback(CmdCallback),cmd);
11     }
12 }

以下为回调函数:

1 private void CmdCallback( IAsyncResult result )
2 {
3      SqlCommand cmd = (SqlCommand)result,AsyncState;
4      SqlDataReader reader = cmd.EndExecuteReader(result);
5 }

 

当然异步还有对 XML 数据的异步执行有关方法如下:

  1. BeginExecuteXmlReader
  2.    BeginExecuteXmlReader(AsyncCallback, Object)
  3. EndExecuteXmlReader

关于 SqlCommand 的学习到此结束了,下面我将要开始 SqlDataAdapter 的学习