.net 通过过滤另一个 DataTable 创建一个 DataTable
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4521919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a DataTable by filtering another DataTable
提问by Jeff Dege
I'm working on a system that currently has a fairly complicated function that returns a DataTable, which it then binds to a GUI control on a ASP.NET WebForm.
我正在开发一个系统,该系统目前有一个相当复杂的函数,它返回一个 DataTable,然后它绑定到 ASP.NET WebForm 上的 GUI 控件。
My problem is that I need to filter the data returned - some of the data that is being returned should not be displayed to the user.
我的问题是我需要过滤返回的数据——一些返回的数据不应该显示给用户。
I'm aware of DataTable.select(), but that's not really what I need. First, it returns an array of DataRows, and I need a DataTable, so I can databind it to the GUI control. But more importantly, the filtering I need to do isn't something that can be easily put into a simple expression. I have an array of the elements which I do not want displayed, and I need to compare each element from the DataTable against that array.
我知道 DataTable.select(),但这并不是我真正需要的。首先,它返回一个 DataRows 数组,我需要一个 DataTable,以便我可以将它数据绑定到 GUI 控件。但更重要的是,我需要做的过滤不是可以轻松放入简单表达式的东西。我有一个我不想显示的元素数组,我需要将 DataTable 中的每个元素与该数组进行比较。
What I could do, of course, is to create a new DataTable, reading everything out of the original, adding to the new what is appropriate, then databinding the new to the GUI control. But that just seems wrong, somehow. In this case, the number of elements in the original DataTable aren't likely to be enough that copying them all in memory is going to cause too much trouble, but I'm wondering if there is another way.
当然,我可以做的是创建一个新的 DataTable,从原始数据中读取所有内容,将适当的内容添加到新数据中,然后将新数据绑定到 GUI 控件。但这似乎是错误的,不知何故。在这种情况下,原始 DataTable 中的元素数量可能不够,以至于将它们全部复制到内存中会造成太多麻烦,但我想知道是否有其他方法。
Does the .NET DataTable have functionality that would allow me to filter via a callback function?
.NET DataTable 是否具有允许我通过回调函数进行过滤的功能?
采纳答案by Jhonny D. Cano -Leftware-
What about binding the GUI Control To a List of DataRows which satisfies your condition? something like this:
将 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
Doing it this way, the datarows won't be copied, but the list will keep the references to the rows you need.
这样做,数据行不会被复制,但列表将保留对您需要的行的引用。
回答by Thomas Levesque
Use the DataView.ToTablemethod:
使用DataView.ToTable方法:
DataTable sourceTable = ...
string filter = ...
string sort = ...
DataView view = new DataView(sourceTable, filter, sort, DataViewRowState.CurrentRows);
DataTable newTable = view.ToTable();
If you can't put your filtering logic in a filter expression, you can resort to Linq to DataSet:
如果您不能将过滤逻辑放在过滤器表达式中,则可以使用Linq 到 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();
Or, if you already have a method that implements the filtering:
或者,如果您已经有一个实现过滤的方法:
bool FilterRow(DataRow row)
{
...
}
...
var newTable = sourceTable.AsEnumerable().Where(FilterRow).AsDataView().ToTable();
回答by Tim Schmelter
I don't know what you mean with a callback function.
我不知道你说的回调函数是什么意思。
Probably others will recommend LINQfor this. But because i'm still using 3.5 Framework, i'm not familiar with it.
可能其他人会为此推荐LINQ。但是因为我还在使用 3.5 Framework,所以我不熟悉它。
How many rows does your Datatable have? It might be sufficient to use Datatable.Select:
您的数据表有多少行?使用 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
You can also use a Dataview as source of your second control with using its RowFilterproperty:
您还可以使用 Dataview 作为第二个控件的源,并使用其RowFilter属性:
DataView dv = new DataView( sourceDataTable );
dv.RowFilter = selectFilter
GridView1.DataSource = dv
You can also use the INand NOT INSyntax to filter by a list/array of items for Select and RowFilter, for example:
您还可以使用INandNOT IN语法按 Select 和 RowFilter 的项目列表/数组进行过滤,例如:
dv.RowFilter = "SomeID NOT IN(1,2,3)"

