2016-08-14 52 views
1

我正在爲自己的時間構建一個註冊類型的web應用程序,並且我想出了一點麻煩。基於多個複選框的Gridview過濾器

基本上我想讓Gridview根據選擇的複選框來改變它顯示的內容。到目前爲止,我已經有了很多工作,但現在當我嘗試讓它根據多個選擇進行篩選時,它會拋出關於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(); 
    } 

回答

0

WHERE語句缺少結束動態),對不起,我我的手機上,並用引號回答是不容易的

+0

你可以在連接創建之前放一個break,並且發佈名爲'condition'的變量的值嗎? – Kbalz

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)); 

看到在第二行添加了一個「)」。

+0

乾杯,固定了,但仍然沒有害怕。會發生什麼是當我勾選Type複選框時,Gridview會改變,但是當我勾選任何一個Location複選框時,它會在WHERE語句附近出現語法錯誤 – Zooch84

0

也許是因爲類型和位置的「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(); 
       } 
      } 
     } 
    } 
} 
+0

以您的示例爲例,它會引發錯誤,指出Length不能小於零,這是因爲沒有選擇任何東西,並且沒有執行價值? – Zooch84

+0

@ Zooch84你是對的,我在答案的代碼示例中添加了條件。 – renouve