我正在开发一个系统,该系统当前有一个相当复杂的函数,该函数返回一个 DataTable,然后将其绑定到 ASP.NET WebForm 上的 GUI 控件。
我的问题是我需要过滤返回的数据 - 某些返回的数据不应显示给用户。
我知道 DataTable.select(),但这并不是我真正需要的。首先,它返回一个 DataRows 数组,我需要一个 DataTable,以便我可以将其数据绑定到 GUI 控件。但更重要的是,我需要做的过滤并不是可以轻松放入简单表达式中的东西。我有一个不想显示的元素数组,我需要将 DataTable 中的每个元素与该数组进行比较。
当然,我可以做的是创建一个新的 DataTable,读取原始数据中的所有内容,添加到新数据中适当的内容,然后将新数据绑定到 GUI 控件。但不知何故,这似乎是错误的。在这种情况下,原始 DataTable 中的元素数量可能不够,将它们全部复制到内存中会造成太大麻烦,但我想知道是否还有其他方法。
.NET DataTable 是否具有允许我通过回调函数进行过滤的功能?
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();
将 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
这样做,数据行不会被复制,但列表将保留对您需要的行的引用。
我不知道你所说的回调函数是什么意思。
可能其他人会为此推荐 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)"
如果 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;
我该如何处理这个空检查?