DataReader和子程序问题

时间:2014-02-05 04:14:43

标签: c# sqldatareader static-variables

我的第一个子过程使用参数搜索数据库并将字段返回到表单。应该循环到下一个读者的我的第二个子程序没有按计划工作。

我被告知所有我要做的就是建立连接,dReader和cmd字符串静态变量,然后再次调用读取器循环到第二个子过程中的下一个记录......

我收到此错误:对象引用未设置为对象的实例。当我按下第一个按钮时,搜索工作并且它会拉出第一个记录,但是当我单击“下一个”记录按钮并进入第二个子过程时,当它到达if(dReader.HasRows)时会出现错误其中说“对象引用没有设置为对象的实例”如何让dReader在第一个子程序中从它停止的位置读取行?

<%@ 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();

    }
}   

2 个答案:

答案 0 :(得分:0)

你在这里犯了一些错误。在下面的代码中,using块会在离开块时放置dReader

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

并且在处置完毕后你不能使用相同的dReader

另一个问题是你有static System.Data.SqlClient.SqlDataReader dReader;但是在btnFirst_Click方法中你正在创建方法级别dReader

我会将搜索结果加载到DataSet/DataTable并将其用于UI。您可以使用FormView

在页面加载中,执行以下操作

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

答案 1 :(得分:0)

在第一个按钮单击处理程序中,您将使用using数据块作为SQLDataReader对象。在该块的末尾,该对象被关闭。因此,当您尝试在第二个处理程序中使用相同的对象时,该对象将再次为null。

您可以通过在第二个处理程序中使用与第一个处理程序相同的代码来填充对象来解决此问题。