基于多个复选框的Gridview过滤器

时间:2016-08-14 02:28:19

标签: c# asp.net gridview

我正在为自己的时间构建一个注册类型的Web应用程序,我想起了一点麻烦。

基本上我试图让Gridview根据选择的Checkbox更改显示的内容。到目前为止,我已经完成了它的工作,但现在当我尝试根据多个选择进行过滤时,它会抛出有关WHERE语句的错误。现在我知道实际问题是什么,我只是绞尽脑汁试图找出解决方案。

理想情况下,我希望位置&键入检查一起完成,但似乎foreach语句不喜欢其中的OR运算符..

感谢您的帮助

HTML代码:

       <div class="row">
        <div class="col">
       <asp:Label ID="Label1" runat="server" style="font-weight: 700" Text="Location"></asp:Label>
       <asp:CheckBoxList ID="chklocation" runat="server" AutoPostBack="true" OnSelectedIndexChanged="Location_Selected">
        <asp:ListItem Text="Sydney" Value="Sydney"></asp:ListItem>
        <asp:ListItem Text="Melbourne" Value="Melbourne"></asp:ListItem>
        <asp:ListItem Text="Canberra" Value="Canberra"></asp:ListItem>
        <asp:ListItem Text="Darwin" Value="Darwin"></asp:ListItem>
        <asp:ListItem Text="Perth" Value="Perth"></asp:ListItem>
    </asp:CheckBoxList>
    </div>

     <div class="col">
     <asp:Label ID="Label2" runat="server" style="font-weight: 700" Text="Type"></asp:Label>
        <asp:CheckBoxList ID="chktype" runat="server" AutoPostBack="true" OnSelectedIndexChanged="Type_Selected">
             <asp:ListItem Text="Desktop" Value="Desktop"></asp:ListItem>
             <asp:ListItem Text="Laptop" Value="Laptop"></asp:ListItem>
         </asp:CheckBoxList>
     </div>
     </div>

代码隐藏:

  protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            this.BindGrid();
        }

    }

private void BindGrid()
    {
       string VDIListConnectionString =    ConfigurationManager.ConnectionStrings["VDIListConnectionString"].ConnectionString;
        string query = "SELECT UserName, Location, Type, Active, ImageNumber FROM VDI";

        string condition = string.Empty;
        foreach (ListItem item in chklocation.Items) 
        {
            condition += item.Selected ? string.Format("'{0}',", item.Value) : string.Empty;
        }

        if (!string.IsNullOrEmpty(condition))
        {
            condition = string.Format(" WHERE Location IN ({0}) AND Type IN ({0})", condition.Substring(0, condition.Length - 1));
        }

        foreach (ListItem item in chktype.Items)
        {
            condition += item.Selected ? string.Format("'{0}',", item.Value) : string.Empty;
        }

        if (!string.IsNullOrEmpty(condition))
        {
            condition = string.Format(" WHERE Type IN ({0} AND Location IN ({0})", condition.Substring(0, condition.Length - 1));
        }

        using (SqlConnection con = new SqlConnection(VDIListConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand(query + condition))
            {
                using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                {
                    cmd.Connection = con;
                    using (DataTable dt = new DataTable())
                    {
                        sda.Fill(dt);
                        GridView1.DataSource = dt;
                        GridView1.DataBind();
                    }
                }
            }
        }
      }

    protected void OnPageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GridView1.PageIndex = e.NewPageIndex;
        this.BindGrid();
    }


    protected void Location_Selected(object sender, EventArgs e)
    {
        this.BindGrid();
    }

    protected void Type_Selected(object sender, EventArgs e)
    {
        this.BindGrid();
    }

3 个答案:

答案 0 :(得分:0)

动态where语句缺少关闭)抱歉我在手机上并且用引号回答并不容易

答案 1 :(得分:0)

要澄清Kbalz的答案,请尝试替换此行:

condition = string.Format(" WHERE Type IN ({0} AND Location IN ({0})", condition.Substring(0, condition.Length - 1));

通过这个:

condition = string.Format(" WHERE Type IN ({0}) AND Location IN ({0})", condition.Substring(0, condition.Length - 1));

在第二行中看到&#34;)&#34;已被添加。

答案 2 :(得分:0)

也许是因为Type和Location的“IN”值在查询中是相同的。你能试试这个:

private void BindGrid()
{
    string VDIListConnectionString = ConfigurationManager.ConnectionStrings["VDIListConnectionString"].ConnectionString;
    string query = "SELECT UserName, Location, Type, Active, ImageNumber FROM VDI";

    string condition = string.Empty;
    string locations = string.Empty;
    string types = string.Empty;

    foreach (ListItem item in chklocation.Items)
        locations += item.Selected ? string.Format("'{0}',", item.Value) : string.Empty;

    if (!string.IsNullOrEmpty(locations))
        locations = locations.Substring(0, locations.Length - 1);

    foreach (ListItem item in chktype.Items)
        types += item.Selected ? string.Format("'{0}',", item.Value) : string.Empty;

    if (!string.IsNullOrEmpty(types))
        types = types.Substring(0, types.Length - 1);

    var subConditions = new List<string>();

    if (!string.IsNullOrEmpty(locations))
        subConditions.Add(string.Format("Location IN ({0})", locations));

    if (!string.IsNullOrEmpty(types))
        subConditions.Add(string.Format("Type IN ({0})", types));

    if (subConditions.Any())
        condition = " WHERE " + subConditions.Aggregate((c, n) => string.Format("{0} AND {1}", c, n));

    using (SqlConnection con = new SqlConnection(VDIListConnectionString))
    {
        using (SqlCommand cmd = new SqlCommand(query + condition))
        {
            using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
            {
                cmd.Connection = con;
                using (DataTable dt = new DataTable())
                {
                    sda.Fill(dt);
                    GridView1.DataSource = dt;
                    GridView1.DataBind();
                }
            }
        }
    }
}