3

我正在寻找一种有效的方法来搜索数据集以查看项目是否存在。我有一个约 6000 个项目的数组列表,我需要通过将数组列表中的每个项目与数据集特定列中的数据进行比较来确定数据集中不存在哪些项目。

我试图为数组列表中的每一项循环遍历数据集中的每一项,但这需要很长时间。然后我尝试使用下面的 RowFilter 方法。其中没有一个看起来是有效的。非常感谢任何帮助,因为您可以告诉我我不是一个程序员......

例子:

Dim alLDAPUsers As ArrayList
alLDAPUsers = clsLDAP.selectAllStudents

Dim curStu, maxStu As Integer
maxStu = alLDAPUsers.Count

For curStu = 0 To maxStu - 1
     Dim DomainUsername As String = ""
     DomainUsername = alLDAPUsers.Item(curStu).ToString

     Dim filteredView As DataView
     filteredView = dsAllStudents.Tables(0).DefaultView
     filteredView.RowFilter = ""
     filteredView.RowFilter = "szvausr_un = '" & DomainUsername & "'"

     Dim returnedrows As Integer = filteredView.Count
     If returnedrows = 0 Then
          '' Delete the user...
     End If
Next
4

5 回答 5

4

您可以通过对列表进行排序并对数据集进行排序来获得更好的性能。然后,您可以将它们放在一起,边走边匹配。尤其如此,因为您可能已经至少(或者,您应该)在创建它的 sql 查询中对数据集进行了排序,从而使该步骤基本上是免费的。

您应该考虑在现有代码上使用通用列表而不是 ArrayList,以及其他一些风格点:

Dim LDAPUsers As List(Of String) = clsLDAP.selectAllStudents

For Each DomainUsername As String in LDAPUsers
     Dim filteredView As DataView = dsAllStudents.Tables(0).DefaultView
     filteredView.RowFilter = "szvausr_un = '" & DomainUsername & "'"

     If filteredView.Count = 0 Then
      '' Delete the user...
     End If
Next

这与您的原始片段做同样的事情,但空间只有一半,所以它更干净,更具可读性。

于 2008-10-28T13:32:08.767 回答
2

尝试将您的数组列表切换到泛型。据我了解,它们比数组列表快得多。

这是以前关于泛型与数组列表的 SO

于 2008-10-28T13:30:52.293 回答
2

如果您按照建议使用泛型,则可以有两个字符串列表并执行以下操作:

for each s as string in LDAPUsers.Except(AllStudents)
    ''Delete the user (s)
next

其中 LDAPUsers 和 AllStudents 都是 List(Of String)

编辑:

您还可以将 except 更改为:

LDAPUsers.Except(AllStudents, StringComparer.InvariantCultureIgnoreCase)

忽略大小写等

编辑2:

获取通用列表可能很简单:

Dim LDAPUsers as new List(Of String)(alLDAPUsers.Cast(Of String))
Dim AllStudents as new List(OfString)()

for each dr as DataRow in dsAllStudents.Tables(0).Rows
    AllStudents.Add(dr("szvausr_un"))
next

或者你可以像 Joel 提到的那样选择 Linq-y 的优点,但不幸的是,我对此的了解是有限的……

于 2008-10-28T13:51:20.897 回答
1

就像其他人所说的那样,泛型或 linq 会是更好的选择。但是,我想指出您不需要使用DataView。数据表有一个Select方法...

dsAllStudents.Tables(0).Select("szvausr_un = '" & DomainUserName & "'")

它返回一个 DataRows 数组。我确信它的性能会和视图一样差,但我认为它更干净一些。

于 2008-11-25T22:49:44.983 回答
0

将 Dim 语句排除在循环之外......您的性能受到重复变量实例化和重新分配的影响。

同时删除您不需要的任何语句(rowfilter = "")

Dim alLDAPUsers As ArrayList
Dim DomainUsername As String
Dim curStu, maxStu As Integer
Dim filteredView As DataView
Dim returnedrows As Integer

alLDAPUsers = clsLDAP.selectAllStudents
maxStu = alLDAPUsers.Count

For curStu = 0 To maxStu - 1
     DomainUsername = alLDAPUsers.Item(curStu).ToString


     filteredView = dsAllStudents.Tables(0).DefaultView
     filteredView.RowFilter = "szvausr_un = '" & DomainUsername & "'"

     returnedrows  = filteredView.Count
     If returnedrows = 0 Then
          '' Delete the user...
     End If
Next
于 2008-10-28T13:33:23.567 回答