在单个连接(SqlConnection)上执行多个查询块

本文关键字:执行 查询 单个 连接 SqlConnection | 更新日期: 2023-09-27 18:09:41

我有一个示例数据访问方法设计下面递归调用:

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项的情况)

在单个连接(SqlConnection)上执行多个查询块

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

你应该整体思考,而不是单项思考。一次传递要删除的所有项。有关如何实现这一点的详细信息,请参见表值参数。使用单个DELETE语句连接整个参数集。

(回复作为回答,因为我没有得到添加评论选项)-@MarcinJuraszek:给他加5分。默认池大小为100(最大值)。所以它会挂起更多的后续请求。为了克服这个问题,最好的做法是在必要时关闭每个打开的连接。

-当它不被使用时?这意味着在代码末尾关闭连接。不管你的代码需要多少时间来执行,它只会在到达指定代码时关闭连接。connection.close();