从复选框列表顶部的项目中从SQL数据库中选择的数据被复制到所有Gridview行

时间:2019-06-21 12:20:44

标签: c# sql asp.net

我正在尝试创建一个网格视图表,我想在其中显示复选框列表中的一些选定数据。问题是,每当我从复选框列表中选择一些数据时,即使我已经选中了多个框来显示数据,Gridview仍只会显示顶部复选框中的数据,而不会与列表中的每个框绑定多个不同的数据?

当选中一个新框时,Det gridview确实添加了新行,但是新行复制了前一行的数据

gridview和checkboxlist都连接到SQL数据库,数据来自于该数据库:

代码

 public partial class Visual : System.Web.UI.Page
 {
    String con = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public void CheckBoxList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();  
        DataRow dr = dt.NewRow();
        dt.Columns.Add("SensorID");
        dt.Columns.Add("BatteryLife");
        dt.Columns.Add("YearInUsage");
        dt.Columns.Add("NumberOfUsage");
        dt.Columns.Add("Occupations");
        dt.Columns.Add("Placement");
        dt.Columns.Add("Zip");
        dt.Columns.Add("City");

        List<DataListe> dl = new List<DataListe>();

        foreach (ListItem item in CheckBoxList1.Items) 
        {
            SqlConnection sc = new SqlConnection(con);
            sc.Open(); 
            SqlCommand cmd = new SqlCommand("SELECT * FROM Statistic WHERE SensorID='" + CheckBoxList1.SelectedValue + "'", sc); 
            SqlDataReader reader = cmd.ExecuteReader();

            if (item.Selected) 
            {
                while (reader.Read()) 
                {
                    DataListe dali = new DataListe();

                    string si = (string)reader["SensorID"];
                    dali.SensorID = si;

                    string bl = (string)reader["BatteryLife"];
                    dali.BatteryLife = bl;

                    string yu = (string)reader["YearInUsage"];
                    dali.YearInUsage = yu;

                    int nu = (int)reader["NumberOfUsage"];
                    dali.NumberOfUsage = nu;

                    string oc = (string)reader["Occupations"];
                    dali.Occupations = oc;

                    string pl = (string)reader["Placement"];
                    dali.Placement = pl;

                    int zi = (int)reader["Zip"];
                    dali.Zip = zi;

                    string ci = (string)reader["City"];
                    dali.City = ci;


                    dl.Add(dali); 

                }
            }
            sc.Close(); 
        }

        GridView1.DataSourceID = null; 
        GridView1.DataSource = dl;
        GridView1.DataBind();

        return;
}

我希望在选中复选框列表中的新框时,gridview会添加新行,并保持前一行不变。该行应包含与复选框列表中的项目相关的信息,该信息由SQLdatabase提供。

但是,当选中一个新框时,gridview确实添加了新行,但是它从已经显示的行中复制了数据。

2 个答案:

答案 0 :(得分:0)

您的问题是您的代码在“复选框选定的索引更改事件”中。每次您检查另一个条目时,都会触发此代码。由于您没有在运行之前清除数据集,因此会遍历整个复选框列表并添加所有选中的项目。因此,当您检查第一个时,会将其放入数据集中。您检查第二个,它将第一个和第二个放在数据集中,依此类推。

将代码移至“复选框离开事件”或“失去焦点事件”。它只有在离开控件时才会触发。

答案 1 :(得分:0)

代码中的问题是您使用了 CheckboxList1.SelectedValue 。 CheckBoxList的SelectedValue应该是什么?您是否认为无论此值是多少,当您遍历Items集合时它都会改变吗?

您需要改用Item.Value

// Opening the connection just one time before starting the loop
using(SqlConnection sc = new SqlConnection(con))
{
    sc.Open(); 
    string cmdText = "SELECT * FROM Statistic WHERE SensorID=@id";
    foreach (ListItem item in CheckBoxList1.Items) 
    {
        if (item.Selected) 
        {
            // Moved the actual query inside the check for the item.Selected
            // so you are calling the db only for the items that you want to use
           SqlCommand cmd = new SqlCommand(cmdText, sc); 
           cmd.Parameters.Add("@id", SqlDbType.NVarChar).Value = item.Value;
           using(SqlDataReader reader = cmd.ExecuteReader())
           {
               while (reader.Read()) 
               {
                   DataListe dali = new DataListe();
                   dali.SensorID = (string)reader["SensorID"];
                   dali.BatteryLife = (string)reader["BatteryLife"];
                   dali.YearInUsage = (string)reader["YearInUsage"];
                   dali.NumberOfUsage = (int)reader["NumberOfUsage"];
                   dali.Occupations = (string)reader["Occupations"];
                   dali.Placement = (string)reader["Placement"];
                   dali.Zip = (int)reader["Zip"];
                   dali.City = (string)reader["City"];
                   dl.Add(dali); 
             }
        } // At this point the reader is closed and disposed by the ending using block
    }
}  // At this point the connection is closed and disposed by the ending using block

其他注意事项:当不再需要连接和读取器之类的一次性对象时,应将其丢弃。 using语句即使在出现异常的情况下也可以确保这一点。另一个非常重要的方面是当您要将查询文本传递到数据库引擎时使用参数。将字符串串联在一起是确定自己遇到Sql Injection问题和可能的解析错误的可靠方法。