【发布时间】:2021-01-30 06:25:27
【问题描述】:
如何使用变量 Itmnmbr 而不是硬编码其值 'i-2051'?
Dim fr() As DataRow
Dim Itmnmbr As string = "i-2051"
fr = dt.Select("item = 'i-2051'")
【问题讨论】:
如何使用变量 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(...)
itemNunmber 比 Itmnmbr 更易于阅读,filteredRows 比 fr 更明确。在这种情况下,有一些 convection 是大多数人习惯的,例如 dt 用于 DataTable,ds 用于 DataSet 等。最好确保当您在一段时间后阅读您的代码时,您不会对自己生气:)
注意,Interpolated String 和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(需要对 System.Data.DataSetExtensions 程序集的项目引用 - 通常已与 System.Data 一起链接),让您使用 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 和 Best practices for comparing strings in .NET
最后这两个方法不返回 DataRow 对象引用的数组,而是一个 EnumerableRowCollection。优点是(当您可以使用它时)集合仅在您实际使用它时返回(执行被延迟)。
如果使用得当,它可以提高代码的性能。试试看。
除了DataTable.Select(),您还可以使用其DefaultView.RowFilter 属性过滤您的DataTable。
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() 返回的行集合包含对 DataTable 中行的引用。
例如,如果您考虑 Collection 和过滤后的 DataTable:
Dim filteredRows = dt.Select($"item = '{itemNumber}'")
dt.DefaultView.RowFilter = $"item = '{itemNumber}'"
假设filteredRows 包含一个行。然后应用过滤器。
如果你现在改变filteredRows(0)("item")的值:
filteredRows(0)("item") = "Some other value"
当您在 UI 中显示 DataTable 时,将不会显示任何行,因为过滤器处于活动状态,并且现在没有任何行符合过滤器的条件:设置 filteredRows(0)("item") 已更改它所引用的行的值。
要删除过滤器,请将其设置为 string.Empty:
dt.DefaultView.RowFilter = Sting.Empty
要恢复之前保存的过滤器:
dt.DefaultView.RowFilter = previousFilter
【讨论】:
Dim previousFilter = dt.DefaultView.RowFilter = $"item = '{itemNumber}'" 时,它不会改变 DataGridView 中的显示。 dt.DefaultView.RowFilter = $"item = '{itemNumber}'" 过滤数据。 previousFilter 是一个 Boolean 和 ,似乎第二个 = 是一个比较,而不是一个赋值。我在哪里偏离轨道?