通过过滤另一个数据表来创建数据表

问题描述 投票:0回答:4

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

我的问题是我需要过滤返回的数据 - 某些返回的数据不应显示给用户。

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

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

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

.net datatable
4个回答
22
投票

使用

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

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

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


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

您还可以使用

IN
NOT IN
语法按 Select 和 RowFilter 的项目列表/数组进行筛选,例如:

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

0
投票

如果 row.Field("bar") 值之一为 null, 我想用“startDate”替换空值。

我该怎么办呢。我尝试过类似的事情,但没有运气

datetime dob = "05152024";
var query = from row in maxLookupData.AsEnumerable() 
     where row.IsNull(Field<DateTime>("bar")? dob ) <=  dob 
select row;

我该如何处理这个空检查?

© www.soinside.com 2019 - 2024. All rights reserved.