Question

My first subprocedure searches a database using a parameter and returns fields to a form. My 2nd subprocedure which is supposed to cycle to the next reader isn't working as planned.

I was told all I would have to do is make the connection, dReader, and cmd strings static variables, and then just call the reader again to cycle to the next record in the 2nd subprocedure...

I'm getting this error : Object reference not set to an instance of an object. When I press the first button, the search works and it pulls up the first record, but when I click the 'Next' record button and it goes to the 2nd subprocedure, when it gets to the if(dReader.HasRows) it gets an error which says "Object reference not set to an instance of an object" How can I get dReader to pickup on reading rows from where it left off in the first subprocedure?

<%@ Page Title="Home Page" Language="C#"%>

<script runat = "server" >

static System.Data.SqlClient.SqlConnection conn;
static System.Data.SqlClient.SqlCommand cmd;
static System.Data.SqlClient.SqlDataReader dReader;
protected void btnFirst_Click(object sender, EventArgs e)
{
    txtFirst.Text = "";
    txtMiddle.Text = "";
    txtLast.Text = "";
    txtAddress1.Text = "";
    txtAddress2.Text = "";
    txtCity.Text = "";
    txtState.Text = "";
    txtZip.Text = "";
    var conn = new System.Data.SqlClient.SqlConnection(@"Server=IDEA-PC\LOCALHOST;Database=Student;Trusted_Connection=True;");

    try
    {
        conn.Open();
    }
    catch (Exception ex)
    {
        lblSearch.Text = "Connection Error! " + ex;
    }

    var cmd = new System.Data.SqlClient.SqlCommand("SELECT FirstName, MiddleName, LastName, AddressLine1, AddressLine2, City, State, PostalCode from dbo.Person INNER JOIN dbo.Address on dbo.Person.StudentID = dbo.Address.StudentID " +
        "where dbo.Person.FirstName LIKE @Name order by FirstName", conn);

    cmd.Parameters.AddWithValue("@Name", "%" + txtSearch.Text + "%");
    System.Data.SqlClient.SqlDataReader dReader = cmd.ExecuteReader();

    String s = "";
    if (txtSearch.Text == s)
    {
        lblSearch.Text = "Please enter a name!";

    }
    else
    {
        if (dReader.HasRows)
        {

            dReader.Read();
            txtFirst.Text = dReader["FirstName"].ToString();
            txtMiddle.Text = dReader["MiddleName"].ToString();
            txtLast.Text = dReader["LastName"].ToString();
            txtAddress1.Text = dReader["AddressLine1"].ToString();
            txtAddress2.Text = dReader["AddressLine2"].ToString();
            txtCity.Text = dReader["City"].ToString();
            txtState.Text = dReader["State"].ToString();
            txtZip.Text = dReader["PostalCode"].ToString();
            dReader.Close();
        }
        else
        {
            lblSearch.Text = "No Data Found!";
        }
    }
    conn.Close();
}

protected void btnNext_Click(object sender, EventArgs e)
{
    if (dReader.HasRows)
    {
        dReader.Read();
        txtFirst.Text = dReader["FirstName"].ToString();
        txtMiddle.Text = dReader["MiddleName"].ToString();
        txtLast.Text = dReader["LastName"].ToString();
        txtAddress1.Text = dReader["AddressLine1"].ToString();
        txtAddress2.Text = dReader["AddressLine2"].ToString();
        txtCity.Text = dReader["City"].ToString();
        txtState.Text = dReader["State"].ToString();
        txtZip.Text = dReader["PostalCode"].ToString();

    }
}   

Was it helpful?

Solution

You are making a few mistakes here. In the code below, the using block will dispose the dReader when it leave the block

  using (System.Data.SqlClient.SqlDataReader dReader = cmd.ExecuteReader())

and you can't use the same dReader after it has been disposed.

Another issue is that you have static System.Data.SqlClient.SqlDataReader dReader; but inside btnFirst_Click method you are creating the method level dReader

I would load the search results to a DataSet/DataTable and use that for the UI. You can use FormView for this.

In the page load, do as below

formView.DataSource = dataTable;
formView.DataBind();

OTHER TIPS

In your first button click handler, you use the using block for your SQLDataReader object. At the end of that block, the object is closed. As a result, when you try to use the same object in your second handler, the object is null again.

You can remedy this by using same code as first handler in your second handler to populate the object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top