通过过滤另一个DataTable来创建DataTable

时间:2010-12-23 19:42:04

标签: .net datatable

我正在开发一个系统,该系统目前有一个相当复杂的函数,它返回一个DataTable,然后它绑定到ASP.NET WebForm上的GUI控件。

我的问题是我需要过滤返回的数据 - 不应该向用户显示一些正在返回的数据。

我知道DataTable.select(),但这不是我真正需要的。首先,它返回一个DataRows数组,我需要一个DataTable,所以我可以将它数据绑定到GUI控件。但更重要的是,我需要做的过滤不是可以轻松放入简单表达式的东西。我有一个我不想显示的元素数组,我需要将DataTable中的每个元素与该数组进行比较。

当然,我能做的就是创建一个新的DataTable,读取原始的所有内容,添加新的适当的内容,然后将新的数据绑定到GUI控件。但不知何故,这似乎是错误的。在这种情况下,原始DataTable中的元素数量可能不足以将它们全部复制到内存中会导致太多麻烦,但我想知道是否还有其他方法。

.NET DataTable是否具有允许我通过回调函数进行过滤的功能?

3 个答案:

答案 0 :(得分:16)

使用DataView.ToTable方法:

DataTable sourceTable = ...
string filter = ...
string sort = ...
DataView view = new DataView(sourceTable, filter, sort, DataViewRowState.CurrentRows);
DataTable newTable = view.ToTable();

如果您无法将过滤逻辑放在过滤器表达式中,则可以使用Linq to DataSet

var query = from row in sourceTable.AsEnumerable()
            where row.Field<int>("foo") > 42
            && row.Field<string>("bar") == "hello"
            && ...
            select r;

var newTable = query.AsDataView().ToTable();

或者,如果您已经有一个实现过滤的方法:

bool FilterRow(DataRow row)
{
    ...
}

...

var newTable = sourceTable.AsEnumerable().Where(FilterRow).AsDataView().ToTable();

答案 1 :(得分:2)

如何将GUI控件绑定到满足您条件的DataRows列表?像这样的东西:

var lst = new List<DataRow>();
foreach(DataRow dr in dt.Rows) {
  if (SatisfiesCondition(dr)) lst.Add(dr);
}

// in Linq dialect
var lst = dt.AsEnumerable().Where(SatisfiesCondition).ToList();

// here: bind control to list

这样做,数据行不会被复制,但列表将保留对你需要的行的引用。

答案 2 :(得分:1)

我不知道你对回调函数的意思

其他人可能会为此推荐LINQ。但是因为我还在使用3.5 Framework,所以我不熟悉它。

您的数据表有多少行?使用Datatable.Select:

可能就足够了
Private Function SelectIntoDataTable(ByVal selectFilter As String, ByVal sourceDataTable As DataTable) As DataTable
    Dim newDataTable As DataTable = sourceDataTable.Clone
    Dim dataRows As DataRow() = sourceDataTable.Select(selectFilter)
    Dim typeDataRow As DataRow

    For Each typeDataRow In dataRows
        newDataTable.ImportRow(typeDataRow)
    Next
    Return newDataTable
End Function

您还可以使用Dataview作为第二个控件的来源,并使用其RowFilter属性:

DataView dv = new DataView( sourceDataTable );
dv.RowFilter = selectFilter 
GridView1.DataSource = dv

您还可以使用INNOT IN语法按Select和RowFilter的项目列表/数组进行过滤,例如:

dv.RowFilter = "SomeID NOT IN(1,2,3)"