2012-08-14 27 views
0

我正在我的.aspx頁面中填充一個DataGrid,並在頁面上有一些下拉列表,用於過濾出現在網格中的數據。我正嘗試使用LINQ來過濾綁定到page_load和下拉菜單的SelecedIndexChanged事件的DataTable中的數據。我是否正確使用LINQ來應用可變數量的過濾器?

這是我目前的做法:

Dim filteredData As DataTable = (From d In rawDataTable 
          Select d).CopyToDataTable 

     If Me.cbFilter1.SelectedIndex > 0 Then 

      filteredData = (From f In filteredData 
          Where f.Field(Of Date)("ADateField").Year = Me.cbFilter1.SelectedValue 
          Select f).CopyToDataTable 

     End If 

     If Me.cbFilter2.SelectedIndex > 0 Then 

      filteredData = (From f In filteredData 
          Where f.Field(Of String)("AStringField") = Me.cbFilter2.SelectedValue 
          Select f).CopyToDataTable 

     End If 

     If Me.cbFilter3.SelectedIndex > 0 Then 

      filteredData = (From f In filteredData 
          Where f.Field(Of Boolean)("ABooleanField") = (cbFilter3.SelectedValue = "Yes") 
          Select f).CopyToDataTable 

     End If 

     ' ...and finally binding my grid to filteredData 

是否有一個更清潔,更有效的方式來做到這一點?你會怎麼做? 謝謝!

+0

不知道如果我的標題正確地描述了我在問什麼這裏 – unnknown 2012-08-14 14:32:25

回答

1

你想要使用的是接口來處理添加多個where子句。 IQueryable允許您將Where子句連接到查詢,同時推遲查詢的執行,直到您準備好查詢結果爲止。您所描述的方式多次執行查詢。最重要的是,您每次都調用.CopyToDataTable方法,這可能會有一些額外的性能影響。

除了事實,你應該從數據集和數據表完全搬走,這裏是你使用它們與IQueryable的一個例子,這將有助於:

' Calling the AsQueryable extension method starts your query off as an IQueryable ' 
    Dim query = (From d In rawDataTable 
       Select d).AsQueryable() 

    If Me.cbFilter1.SelectedIndex > 0 Then 
     query = query.Where(Function(f) f.Field(Of Date)("ADateField") = Me.cbFilter1.SelectedValue) 
    End If 

    If Me.cbFilter2.SelectedIndex > 0 Then 
     query = query.Where(Function(f) f.Field(Of String)("AStringField") = Me.cbFilter2.SelectedValue) 
    End If 

    If Me.cbFilter3.SelectedIndex > 0 Then 
     query = query.Where(Function(f) f.Field(Of Boolean)("ABooleanField") = (cbFilter3.SelectedValue = "Yes")) 
    End If 

    ' At this point, you shouldn't even need the .CopyToDataTable() method. ' 
    MyGrid.DataSource = query 
    MyGrid.DataBind() 
+0

太棒了!感謝您的見解 – unnknown 2012-08-14 14:51:12

2

試試吧。

filteredData = (From f In filteredData 
    Where ((Me.cbFilter1.SelectedIndex > 0 And f.Field(Of Date)("ADateField").Year = Me.cbFilter1.SelectedValue) Or _ 
(Me.cbFilter2.SelectedIndex > 0 And f.Field(Of String)("AStringField") = Me.cbFilter2.SelectedValue)) 
    Select f).CopyToDataTable 
2

爲什麼每次都執行CopyToDataTable?我會從原始數據構建查詢,並在最後執行此步驟。

Dim query = From d In rawDataTable Select d 

If Me.cbFilter1.SelectedIndex > 0 Then 
    query = query.Where(Function(f) f.Field(Of Date)("ADateField").Year = Me.cbFilter1.SelectedValue) 
End If 

If Me.cbFilter2.SelectedIndex > 0 Then 
    query = query.Where(Function(f) f.Field(Of String)("AStringField") = Me.cbFilter2.SelectedValue) 
End If 

If Me.cbFilter3.SelectedIndex > 0 Then 
    query = query.Where(Function(f) f.Field(Of Boolean)("ABooleanField") = (cbFilter3.SelectedValue = "Yes")) 
End If 

Dim filteredData As DataTable = query.CopyToDataTable 

注意:結合不同的where子句是完全合法的。結果與用「And」連接條件相同。

+0

不錯。這就是我一直在尋找 – unnknown 2012-08-14 14:52:04