3

データセットを検索してアイテムが存在するかどうかを確認する効率的な方法を探しています。〜 6000 アイテムの配列リストがあり、配列リスト内の各アイテムをデータセットの特定の列のデータと比較して、データセットに存在しないアイテムを特定する必要があります。

arraylist 内の各項目について、データセット内の各項目をループしようとしましたが、それには時間がかかりました。次に、以下の 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

提案されているようにジェネリックスを使用する場合は、文字列のリストを2つ作成して、次のようにすることができます。

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

LDAPUsersとAllStudentsが両方ともList(Of String)である場合

編集:

例外を次のように変更することもできます。

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

または、ジョエルが述べているように、Linq-yの良さで行くこともできますが、残念ながら、それに対する私の露出は限られています...

于 2008-10-28T13:51:20.897 に答える
2

配列リストを Generics に切り替えてみてください。私が理解していることから、それらは配列リストよりもはるかに高速です。

Generics vs Array Listに関する以前の SO は次のとおりです。

于 2008-10-28T13:30:52.293 に答える
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 に答える