如何获取sql结果并在标题中填充标签?

时间:2016-09-29 15:08:14

标签: c# sql asp.net

我正在尝试更改我的代码。我在编写代码的过程中,我的C#/ ASP.Net应用程序的许多部分都使用LINQ to SQL,许多部分使用命令直接访问sql数据库。我觉得我应该标准化这些,所以我正在改变LINQ to SQL代码。我有一部分代码根据会话变量获取找到一条记录,然后用sql查询结果填充我标题中的标签。这是代码:

protected void Page_Load(object sender, EventArgs e)
{
    var pinNum = MySession.Current.focusParcel;

    if (pinNum != 0)
    {
        String sql = ConfigurationManager.ConnectionStrings["Recorder"].ConnectionString;

        SqlConnection connection = new SqlConnection(sql);
        connection.Open();

        SqlCommand command = new SqlCommand("Select PARCEL, PIN_TXT, Owner, Address1, Address2, CSZ, ACRES, LEGAL, Active FROM[ParcelView] WHERE PARCEL = " + pinNum, connection);

        SqlDataReader selectedParcel = command.ExecuteReader();

        if (selectedParcel != null)
        {
            lblPIN_Num.Text = selectedParcel["PARCEL"].ToString();
            lblPIN_TXT.Text = selectedParcel["PIN_TXT"].ToString();
            lblDateTime.Text = DateTime.Now.ToString("MMMM dd, yyyy");
            lblOwner.Text = selectedParcel["Owner"].ToString();
            lblAddress1.Text = selectedParcel["Address1"].ToString();
            lblAddress2.Text = selectedParcel["Address2"].ToString();
            lblCSZ.Text = selectedParcel["CSZ"].ToString();
            lblAcres.Text = string.Format("{0} Acres", selectedParcel["ACRES"]);
            lblLegal.Text = selectedParcel["LEGAL"].ToString();
            if (selectedParcel["Active"].ToString() == "A")
            {
                lblInactive.Text = " (ACTIVE)";
            }
            else
            {
                lblInactive.Text = " (INACTIVE)";
                lnkAddDocument.Visible = false;
            }
        }
        lblCurrentUser.Text = Page.User.Identity.Name;
        connection.Close();
    }
    else
        Response.Redirect("./ParcelSearch.aspx");
}

我收到以下错误:

  

没有数据时无效尝试读取。

我知道使用的SQL语句在直接用于数据库的sql查询时会返回一条记录。

提前感谢任何建议。我是否应该关注在整个应用程序中访问数据时缺乏一致性?如果是这样,我应该将所有内容转换为LINQ吗?或者将所有内容从LINQ转换出来?我知道MVC的存在并且知道我应该学习并使用它,但是我现在试图转换它的路径太远了。

4 个答案:

答案 0 :(得分:1)

更改

if (selectedParcel != null)

if (selectedParcel.Read())

在开始提取数据之前,您必须先读取数据读取器中的记录。它是一个仅向前游标,开始时不指向记录。 Read()方法使读者前进1,如果成功则返回true / false。

请注意,如果使用上述代码,则无需致电HasRows。只有在有行的情况下才会输入if块,如果没有则返回,则返回false并且不输入该块。

修改

您的代码中存在许多不良做法。

  1. 使用参数化的sql !!这是你可以带走的最重要的事情!
  2. 使用块包裹您的连接,以确保连接始终关闭。
  3. Sql代码更改

    String sql = ConfigurationManager.ConnectionStrings["Recorder"].ConnectionString;
    using(SqlConnection connection = new SqlConnection(sql))
    using(SqlCommand command = new SqlCommand("Select PARCEL, PIN_TXT, Owner, Address1, Address2, CSZ, ACRES, LEGAL, Active FROM [ParcelView] WHERE PARCEL = @pinNum", connection))
    {
        command.Parameters.Add(new SqlParameter("@pinNum", SqlDbType.VarChar){Value = pinNum});
        connection.Open();
        using(SqlDataReader selectedParcel = command.ExecuteReader())
        {
            if (selectedParcel.Read())
            {
                /*code unchanged*/
            }
        }
        /* 1 line code unchanged*/
    }
    

答案 1 :(得分:0)

执行完命令后,您需要实际读取数据:

 SqlDataReader selectedParcel = command.ExecuteReader();
 if (selectedParcel.HasRows)
 {
     selectedParcel.Read();
     ....
     ....

答案 2 :(得分:0)

您应该Read() SqlDataReader

protected void Page_Load(object sender, EventArgs e)
{
    var pinNum = MySession.Current.focusParcel;

    if (pinNum == 0)
       Response.Redirect("./ParcelSearch.aspx");

    String sql = ConfigurationManager.ConnectionStrings["Recorder"].ConnectionString;

    using(SqlConnection connection = new SqlConnection(sql))
    {
       connection.Open();

       SqlCommand command = new SqlCommand("Select PARCEL, PIN_TXT, Owner, Address1, Address2, CSZ, ACRES, LEGAL, Active FROM[ParcelView] WHERE PARCEL =@PinNum ", connection);

       //protect from sql injection
       command.Parameters.AddWithValue(@PinNum, pinNum);

       using(SqlDataReader selectedParcel = command.ExecuteReader())
       {

           if(!selectedParcel.HasRows)
               return;

           SetLabels(selectedParcel);      
        }    
     }

 }

 private void SetLabels(SqlDataReader selectedParcel)
 {
     lblPIN_Num.Text = selectedParcel["PARCEL"].ToString();
     lblPIN_TXT.Text = selectedParcel["PIN_TXT"].ToString();
     lblDateTime.Text = DateTime.Now.ToString("MMMM dd, yyyy");
     lblOwner.Text = selectedParcel["Owner"].ToString();
     lblAddress1.Text = selectedParcel["Address1"].ToString();
     lblAddress2.Text = selectedParcel["Address2"].ToString();
     lblCSZ.Text = selectedParcel["CSZ"].ToString();
     lblAcres.Text = string.Format("{0} Acres", selectedParcel["ACRES"]);
     lblLegal.Text = selectedParcel["LEGAL"].ToString();

     if (selectedParcel["Active"].ToString() == "A")
     {
         lblInactive.Text = " (ACTIVE)";
     }
     else
     {
         lblInactive.Text = " (INACTIVE)";
         lnkAddDocument.Visible = false;
     }

     lblCurrentUser.Text = Page.User.Identity.Name;
}

我重构你的代码看起来有点像。你有不同的问题,因为没有关闭你的阅读器。你对sql注入是开放的,你也应该在单独的类中将连接转移到Db。

答案 3 :(得分:0)

我建议您将此格式用于sqlDatareader,因为它将解析是否已检索到结果,并将自动处理异常:

using(SqlDataReader selectedParcel = command.ExecuteReader())
{
    while (selectedParcel .Read())
    {
        //Assign label text to results
    }
}