简体   繁体   中英

C# SqlConnection inside a loop

first time on stackoverflow. I'm learning how to manage SqlConnection in my WebForm pages, and I want to reach the best practice to do that. In my specific case, I have a loop and there's no way for me to run the code without errors if I don't set a new SqlConnection for every iteration of the loop (the error is about an attempt to read when reader is close). So I declare this in the PageLoad method:

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

Then I have this:

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();
            }
        }
    }
}

In buildParent in the while loop i call "conta", but if I use the same SqlConnection (con) with both the methods I have an error about an attempt to read when reader is close. I'm worried about the connection pool on the web server, particularly concerning the max connection reach. So, where am I wrong? What's the best practice to manage SqlConnection? Thank you.

You open the connection as late as possible, and you dispose as soon as possible. Let the connection pool deal with reclaiming the connections.

I usually write my code like this:

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.

Note: To get a count from a SQL database you better use

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

And execute the query with ExecuteScalar()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM