1

第一次在stackoverflow上。我正在学习如何在我的 WebForm 页面中管理 SqlConnection,并且我想达到最佳实践来做到这一点。在我的具体情况下,我有一个循环,如果我没有为循环的每次迭代设置一个新的 SqlConnection,我就无法运行代码而不出错(错误是关于在阅读器关闭时尝试读取) . 所以我在 PageLoad 方法中声明了这一点:

private SqlConnection con;
protected void Page_Load(object sender, EventArgs e)
{
    con = new SqlConnection(connectionString);
}

然后我有这个:

private int conta(int padre)
{
    string SQL = "SELECT * FROM categories WHERE idp=@idpadre";
    SqlCommand cd = new SqlCommand(SQL, con);
    cd.Parameters.AddWithValue("@idpadre", padre);
    int sub=0;
    try
    {                
        if ((con.State & ConnectionState.Open) <= 0)
        {
            con.Open();
        }

        using (SqlDataReader reader = cd.ExecuteReader())
        {
            while (reader.Read())
            {
                sub++;
            }
        }
    }
    catch (Exception err)
    {
        lbl.Text = "Errore conta!";
        lbl.Text += err.Message;
    }
    finally
    {
        con.Close();

    }
    return sub;
}

protected void buildParent(int padre, int level)
{
    StringBuilder sb = new StringBuilder();
    sb.Append(" ");
    for (int i = 0; i < level; i++)
    {
        sb.Append(HttpUtility.HtmlDecode("&nbsp;&nbsp;&nbsp;&nbsp;"));
    }
    sb.Append("|--");
    selectSQL = "SELECT * FROM categories WHERE idp=@idpadre";
    SqlConnection cn = new SqlConnection(connectionString);
    cmd = new SqlCommand(selectSQL, cn);
    cmd.Parameters.AddWithValue("@idpadre", padre);

    try
    {
        cn.Open();

        using (SqlDataReader read = cmd.ExecuteReader())
        {
            while (read.Read())
            {

                dlParent.Items.Add(new ListItem { Text = sb.ToString() + read["cat"].ToString(), Value = read["idcat"].ToString() });
                int sub = conta(Convert.ToInt32(read["idcat"]));
                //int sub = 0;
                if (sub > 0)
                {
                    buildParent(Convert.ToInt32(read["idcat"]), level + 1);
                }

            }
            read.Close();
        }

    }
    catch (Exception err)
    {
        lbl.Text = "Errore buildParent!";
        lbl.Text += err.Message;
    }
    finally
    {
        cn.Close();
        if (s != null)
        {
            if (!this.IsPostBack)
            {
                buildPage();
                buildLang();
                buildImage();
            }
        }
    }
}

在 while 循环中的 buildParent 中,我调用“conta”,但如果我对这两种方法使用相同的 SqlConnection (con),我会在阅读器关闭时尝试读取错误。我担心网络服务器上的连接池,尤其是最大连接范围。那么,我哪里错了?管理 SqlConnection 的最佳实践是什么?谢谢你。

4

1 回答 1

5

您尽可能晚地打开连接,并尽快处理。让连接池处理回收连接。

我通常这样写我的代码:

using (var conn = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(commandToRun, conn))
{
    cmd.Parameters.AddRange(new[]
        {
            new SqlParameter("myParam", "myvalue"),
            new SqlParameter("myParam", "myvalue")
        });

    conn.Open(); // opened as late as possible
    using (SqlDataReader reader = cd.ExecuteReader())
    {
        while (reader.Read())
        {
            // do stuff.
        }
    }
} // disposed here.

注意:要从 SQL 数据库中获取计数,您最好使用

SELECT count(*) FROM categories WHERE idp=@idpadre

并执行查询ExecuteScalar()

于 2013-03-27T17:34:32.030 回答