0

我在我的 .aspx 页面中填充了一个 DataGrid,并在页面上有一些下拉菜单用于过滤出现在网格中的数据。我正在尝试使用 LINQ 过滤我在 page_load 和下拉菜单的 SelecedIndexChanged 事件上绑定的 DataTable 中的数据。

这是我目前的方法:

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

有没有更清洁和更有效的方法来做到这一点?你会怎么做?谢谢!

4

4 回答 4

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
于 2012-08-14T14:35:22.873 回答
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”连接条件相同。

于 2012-08-14T14:40:55.313 回答
1

您想要使用的是IQueryable处理添加多个 where 子句的接口。 IQueryable允许您将 Where 子句链接到您的查询,同时推迟查询的执行,直到您准备好结果。您概述的方式多次执行查询。最重要的是,您.CopyToDataTable每次都调用该方法,这可能会产生一些额外的性能影响。

除了您可能应该完全摆脱 DataSets 和 DataTables 之外,这里有一个示例可以帮助您将它们与 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()
于 2012-08-14T14:44:14.067 回答
0

代替 LINQ,在 DataTable 上使用 DataView -> http://msdn.microsoft.com/en-us/library/system.data.datatable.defaultview.aspx

filtersData.DefaultView.RowFilter = "AStringField = " & Me.cbFilter2.SelectedValue

filtersData.DefaultView.RowFilter = "ADateField.Year = " & Me.cbFilter1.SelectedValue

等等等等

所以你不要创建新的数据表而是过滤它。

于 2012-08-14T14:33:52.640 回答