2013-04-18 50 views
0

下面我有这一个样本数据访问方法的设计要求递归:在单个连接(SqlConnection)上执行多个查询块吗?

public static void DeleteRecord(SqlConnection connection, string childIds, string parentSheetname) 
{ 
    using (var adapter = new SqlDataAdapter("...", connection)) 
    { 
     //fill a datatable 
     string newIds = "..."; 
     string newParentName = "..."; 

     const string query = "DELETE FROM table " + 
          "WHERE ids in (@ids) AND parent = @parent"; 
     //Here's where recursion takes place 
     DeleteRecord(connection, newIds, newParentName); 

     using (var command = new SqlCommand(query, connection)) 
     { 
      var parameters = new[] { 
       new SqlParameter(...), new SqlParameter(...) 
      } 
      command.Parameters.AddRange(parameters); 
      command.ExecuteNonQuery(); 
     } 



} 

我的问题是:

  1. (作为一个很好的做法)是否还好通过连接作为参数?

  2. DeleteRecord方法放在Task上是否可以,所以每次我调用它时,都没有等待命令执行查询的时间。 (当然在某处有Task.WaitAll(tasks)

  3. 在场景编号2上,连接是否会阻塞通过服务器发送的多个查询?我经历过SQLServer挂起一些查询,如果它有大量的查询执行。 (连接池是默认开启的,所以我不知道,如果这也是这里第3项的情况下)
+0

您应该根据需要使用连接 - 在动作之前打开它,在必要时释放/关闭。不使用连接时,不应保持连接处于打开状态。 – MarcinJuraszek 2013-04-18 07:00:13

+0

@MarcinJuraszek,你什么意思'当它不被使用'?在我上面的代码中,总是使用'connection'对象。每次递归调用需要2至4秒。 – Shermay 2013-04-18 07:03:18

+0

您不应尝试任何共享连接对象 - 理想情况下,您应该为每个命令对象创建一个新的连接对象,将其打开,执行命令(并处理任何结果集)并再次关闭它。在幕后,.NET将最小化* actual *网络连接的数量(请查阅连接池以获取更多信息) – 2013-04-18 07:51:13

回答

1

您无法在连接上同时执行多个语句。如果你想执行多个语句,你需要使用多个连接。然而,在你的情况下,这是一个坏主意。您需要将您的删除包装在事务中以维护数据库的一致性。删除单独连接上的项目无法实现事务一致性。

你应该考虑成套,而不是项目。一次通过所有要删除的项目。有关详细信息,请参阅Table-Valued Parameters。使用连接整个参数集的单个DELETE语句。

+0

我会在'think in sets'方法中重新设计它,并使用'where = 1'来创建动态过滤器。在你回答这个问题之前,我一直在考虑如果我使用'command.BeginExecuteNonQuery()来使用你的[答案](http://stackoverflow.com/questions/1544905/beginexecutenonquery-without-endexecutenonquery#1544978) '。 – Shermay 2013-04-18 08:17:30

0

(回复的答案,因为我没有得到添加评论选项) - @ MarcinJuraszek: +5给他。 默认池大小为100(最大)。因此,它将暂停后续请求。为了克服这个问题,在必要的时候关闭每个开放连接。

- 当它没有被使用?只是意味着在代码结束时关闭连接。它不需要代码执行多少,只要在达到指定的代码时关闭连接connection.close();

+0

传递'connection'是一个坏主意吗? – Shermay 2013-04-18 08:10:13

+0

不可以。但不要连接字符串来构建SQL命令。它使您无法接受意外或故意的SQL注入攻击,这可能会破坏整个数据库。改用参数化查询。像SqlCommand cmd = new SqlCommand(“uname,pswd from emp_details where uname =(at)id and pswd =(at)password”,conn);在此语句后添加:cmd.Parameters.Add(new SqlParameter(“(at)id”,“id here”)); cmd.Parameters。添加(新的SqlParameter(“(at)密码”,“密码在这里”)); – 2013-04-18 08:48:49

+0

你见过我的问题吗? 'var parameters = new [] {SqlParameter(...),new SqlParameter(...)}' – Shermay 2013-04-18 09:07:02