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

发布于 2024-10-09 07:53:07 字数 498 浏览 0 评论 0原文

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

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

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

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

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

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.

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.

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.

Does the .NET DataTable have functionality that would allow me to filter via a callback function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

锦上情书 2024-10-16 07:53:07

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

Use the DataView.ToTable method:

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:

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();
冰之心 2024-10-16 07:53:07

将 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

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

What about binding the GUI Control To a List of DataRows which satisfies your condition? something like this:

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.

南汐寒笙箫 2024-10-16 07:53:07

我不知道你所说的回调函数是什么意思。

可能其他人会为此推荐 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)"

I don't know what you mean with a callback function.

Probably others will recommend LINQ for this. But because i'm still using 3.5 Framework, i'm not familiar with it.

How many rows does your Datatable have? It might be sufficient to use 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 RowFilter property:

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

You can also use the IN and NOT IN Syntax to filter by a list/array of items for Select and RowFilter, for example:

dv.RowFilter = "SomeID NOT IN(1,2,3)"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文