Search code examples
sqlasp.netinitializationusing

How close a connection when using "Using(conn)" as it is causing error within another method that the connection isn't initialized.


I have a page which displays info from a database using a connection string, one is an SqlDataReader where I .open and .close the connection. The other is a

Using(conn)
{
}

The Using runs before the open/close function, and when this occurs its results in an error that the connection isn't initialized correctly. When the Using() function isn't called everything is fine. If I set the connection string in the SqlDataReader function again it works fine, but other wise the string set previously is just empty for it.

I'm new to asp.net and I'm unsure if using Using() on a page is bad practice.

I set the connection string on page load, but if the Using() is ran the connection string s always empty:

    public SqlConnection conn;
    String albumID;

    protected void Page_Load(object sender, EventArgs e)
    {
        conn= new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\connstring.mdf;Integrated Security=True");
        thing1();
        thing_using_Using();
        conn_open_conn_close_thing();
        thing2();
    }

The Using() function:

    public void isAlreadyLiked()
    {
        DataTable dt = new DataTable();
        SqlDataAdapter sda = new SqlDataAdapter("SELECT * FROM Likes WHERE UserID = @userID AND AlbumID = @albumID", conn);
        using (conn)
        {
            sda.SelectCommand.Parameters.AddWithValue("@userID", Session["loggedID"]);
            sda.SelectCommand.Parameters.AddWithValue("@albumID", albumID);

            sda.Fill(dt);

            if (dt.Rows.Count == 0)
            {
                //place Like button here
            }
            else
            {
                //place Unlike button here
            }
        }
    }

The function using just .open and .close:

    public void albumDetails()
    {        
    //if the conn string is set here again its fine, but I don't want to repeat the conn string over and over.    

        SqlCommand comm = new SqlCommand("SELECT * FROM Albums WHERE AlbumID=" + albumID, conn);
        conn.Open();
        SqlDataReader reader = comm.ExecuteReader();
        while (reader.Read())
        {
            string AlbumName = reader["AlbumName"].ToString();
            string AlbumArtist = reader["AlbumArtist"].ToString();
            lblAlbumName.Text += AlbumName;
            lblAlbumArtist.Text += AlbumArtist;
        }
        reader.Close();
        conn.Close();
    }

Solution

  • Keep the connectionstring as a global variable or better read it from the web.config and recreate the SqlConnection every time you need it, destroy it immediately after usage.

    This is the recommended practice for disposable objects like the connection and after all, with Connection Pooling you don't have to worry for performances

    // Here is as fixed text and this could be probematic if 
    // you need to deploy to another environment. 
    // Better to read it from your web.config
    public string conString = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\connstring.mdf;Integrated Security=True"
    ...
    
    protected void Page_Load(object sender, EventArgs e)
    {
      ....
    }
    
    public void isAlreadyLiked()
    {
        DataTable dt = new DataTable();
        using(SqlConnection con = new SqlConnection(conString))
        using(SqlDataAdapter sda = new SqlDataAdapter(".....", conn);
        {
            ......
        }
    }
    
    public void albumDetails()
    {        
        using(SqlConnection con = new SqlConnection(conString))
        using(SqlCommand comm = new SqlCommand(".....", conn);
        {
            conn.Open();
            using(SqlDataReader reader = comm.ExecuteReader())
            {
                while (reader.Read())
                {
                    ...
                }
            }
        }
    }