如何 Select 数据表中的行?

How to Select Rows in a Datatable?

如何使用变量 Itmnmbr 而不是对其值进行硬编码,'i-2051'?

Dim fr() As DataRow
Dim Itmnmbr As string = "i-2051"
fr = dt.Select("item = 'i-2051'")

最直接的方法是使用 Interpolated String,可从 Visual Studio 2015、VB.Net 14:

Dim Itmnmbr As string = "i-2051"
fr = dt.Select($"item = '{Itmnmbr}'")

作为建议,让我们更改变量/字段的名称,以便更容易阅读它们并理解这些对象的用途。例如:

Dim dt as New DataTable()
'[...]
Dim itemNunmber As string = "i-2051"
Dim filteredRows As DataRow() = dt.Select(...)

itemNunmberItmnmbr 更易读,filteredRowsfr 更明确。在这种情况下,有一些大多数人习惯的约定,如DataTable 的dt,DataSet 的ds 等。最好确保一段时间后阅读代码时不会生自己的气:)

请注意,内插字符串与使用 String.Format() 格式化的字符串相同,因此这两者实际上是同一件事:

Dim filteredRows As DataRow() = dt.Select($"item = '{itemNumber}'")
Dim filteredRows As DataRow() = dt.Select(String.Format("item = '{0}'", itemNumber))

设置Option Infer On(应该已经是On),要利用local type inference,可以这样写:

Dim filteredRows = dt.Select($"item = '{itemNumber}'")

并让编译器推断类型。在 Visual Studio 中,如果您将鼠标指针移到变量上,它会告诉您这是什么类型。

如果您需要更多 动态 选择,您还有其他选择。
DataTableExtensions (which require a Project Reference to the System.Data.DataSetExtensions assembly - usually already linked along with System.Data), let you use the the AsEnumerable() 方法。

LINQ to Objects风格中:
这里,使用默认字符串Comparer

Dim filteredRows = 
    dt.AsEnumerable().Where(Function(dr) dr("item").ToString().Equals(itemNumber))

LINQ to SQL风格:
在这里,使用InvariantCulture进行比较。

Dim filteredRows =
    From row In dt.AsEnumerable()
    Where row.Field(Of String)("item").Equals(itemNumber, StringComparison.InvariantCulture)
    Select row

另请参阅:StringComparison and Best practices for comparing strings in .NET

最后这两个方法不return 引用DataRow 对象数组,而是EnumerableRowCollection。优点是(当您可以使用它时)集合仅在您实际使用它时才 returned(执行被推迟)。
如果使用得当,它可以提高代码的性能。试试吧。

除了 DataTable.Select(),您还可以使用其 DefaultView.RowFilter 属性.

过滤数据表
dt.DefaultView.RowFilter = $"item = '{itemNumber}'"
' You can save the filter to restore it later, if needed
Dim previousFilter = dt.DefaultView.RowFilter

当您显示 DataTable 的行时,只会显示满足过滤器定义的条件的行(例如,在排序的 DataGrid 中)。

如前所述,您正在使用此处的参考资料。由 DataTable.Select() 编辑的行集合 return 包含数据表中行的引用。

例如,如果您考虑 Collection 和过滤后的 DataTable:

Dim filteredRows = dt.Select($"item = '{itemNumber}'")
dt.DefaultView.RowFilter = $"item = '{itemNumber}'"

假设 filteredRows 包含单个行。然后你应用一个过滤器。
如果现在更改 filteredRows(0)("item") 的值:

filteredRows(0)("item") = "Some other value"

当您在 UI 中显示数据表时,不会显示任何行,因为过滤器处于活动状态并且现在 none 行符合过滤器的条件:设置 filteredRows(0)("item")已更改其引用的行的值。

要删除过滤器,请将其设置为 string.Empty:

 dt.DefaultView.RowFilter = Sting.Empty

要恢复以前保存的过滤器:

 dt.DefaultView.RowFilter = previousFilter