我正在运行一个返回多个条目的LDAP查询,并将它们存储在SearchResultCollection中。我正在迭代搜索SearchResultCollection:
// results is my SearchResultCollection object
foreach (SearchResult sr in results)
{
... do things to each SearchResult in here ...
}
这似乎是最合乎逻辑的方法,但循环令人难以置信慢。当我使用调试器逐步完成循环时,我发现这是初始化foreach循环的第一步,它花费时间 - 实际的迭代是瞬时的。
此外,当我在调试时查看SearchResultCollection的内容时,手表加载变量的内容的时间也一样长。
我有一个理论认为SearchResultCollection实际上并不包含完整的SearchResult对象,而是引用Active Directory服务器中的条目,然后在迭代SearchResultCollection对象时单独获取这些条目。谁能证实这个理论?是否有更好(更快)的方法来获取一组LDAP条目?
答案 0 :(得分:1)
我遇到了同样的问题,下面帖子中的方法比我自己快得多:
http://msdn.microsoft.com/en-us/library/ms180881(v=vs.80).aspx
...回答你的问题是,似乎你试图通过使用类似的东西在循环中直接处理条目:
If Not UserAccount.GetDirectoryEntry().Properties("sAMAccountName").Value Is Nothing Then sAMAccountName = UserAccount.Properties("sAMAccountName")(0).ToString()
...这对性能产生了极大的影响,你可以通过在循环中将集合添加到Dictionary然后处理字典来解决这个问题:
Dim searchResult As SearchResult
Dim dictLatestLogonDatesTemp As New Dictionary(Of String, Date)
SearchResults1 = mySearcher.FindAll()
For Each searchResult In SearchResults1
Dim propertyKey,sAMAccountName As String
Dim dteLastLogonDate As Date = Nothing
For Each propertyKey In searchResult.Properties.PropertyNames
Dim valueCollection As ResultPropertyValueCollection = searchResult.Properties(propertyKey)
For Each propertyValue As Object In valueCollection
If LCase(propertyKey) = LCase("sAMAccountName") Then sAMAccountName = propertyValue
If LCase(propertyKey) = LCase("lastLogon") Then dteLastLogonDate = Date.FromFileTime(propertyValue)
Next propertyValue
Next propertyKey
If sAMAccountName <> Nothing Then dictLatestLogonDatesTemp.Add(sAMAccountName, dteLastLogonDate)
Next searchResult
有点限制因为字典ony有两个条目,但你可以用逗号分隔其他值或使用字典中的值字典:
Dim tempDictionary As Dictionary(Of String, Dictionary(Of String, String))
希望这有助于某人!
答案 1 :(得分:0)
我想提出的是,将它们添加到数据表中也可以很好地工作,并且比字典具有更多的属性。从迭代2000个用户到搜索结果集合,我花了将近2分钟的时间去不到1-2秒。希望这对其他人有帮助。
Private Sub getAllUsers()
Dim r As SearchResultCollection
Dim de As DirectoryEntry = New DirectoryEntry(GetCurrentDomainPath)
Dim ds As New DirectorySearcher(de)
ds.SearchScope = SearchScope.Subtree
ds.PropertiesToLoad.Add("name")
ds.PropertiesToLoad.Add("distinguishedName")
ds.PropertiesToLoad.Add("objectSID")
ds.Filter = "(&(objectCategory=person)(objectClass=user))" '(!userAccountControl:1.2.840.113556.1.4.803:=2) not disabled users
PleaseWait.Status("Loading Users...")
Application.DoEvents()
r = ds.FindAll()
Dim dt As New DataTable
dt.Columns.Add("Name")
dt.Columns.Add("SID")
For Each sr As SearchResult In r
Dim SID As New SecurityIdentifier(CType(sr.Properties("objectSID")(0), Byte()), 0)
dt.Rows.Add(sr.Properties("name")(0).ToString(), SID.ToString)
Next
With lstResults
lstResults.DataSource = dt
.DisplayMember = "name"
.ValueMember = "SID"
.Items.Sort()
End With
End Sub
答案 2 :(得分:-1)
可能有一些方法可以缩短响应时间: