2

是否可以使用System.DirectoryServices.AccountManagement库和PrincipalSearcher类来检索从调用返回的所有 Principals 的自定义属性FindAll()

我目前正在使用这个例子:http: //msdn.microsoft.com/en-us/library/bb552835%28v=vs.90%29.aspx

但是,当访问我的自定义属性/属性时,它似乎是对 AD 商店的一次额外访问。我希望它在最初调用FindAll().

4

2 回答 2

4

是的,可以在初次调用 FindAll() 时急切地加载所有主体的自定义属性。您只需使用 [DirectoryProperty("YOUR_PROP_NAME")] 属性指定 Microsoft 示例中所述的自定义属性。

通过使用 UserPrincipal 类的 GetUnderlyingSearcher() 方法访问底层 DirectorySearcher 的属性 PropertiesToLoad,您可以看到您的自定义属性包含在要加载的属性集合中。您可以在调试器中检查 PropertiesToLoad 集合。

在我的机器上,该集合总共包含 68 个属性。

问题和性能损失就从这里开始了。此集合中包含的属性越多,检索它们所需的 Active Directory 往返次数就越多。

我做了一些性能测试:

使用 Microsoft 示例检索 200 个 InetOrgPerson 对象大约需要 500 毫秒。

直接使用 DirectorySearcher 类并且只请求感兴趣的属性只需要 70 毫秒(参见下面的示例)。

using (DirectoryEntry e = new DirectoryEntry("LDAP://server10/CN=users,DC=treyresearch,DC=net", 
                                         "treyresearch\\administrator", "P@$$W0rd", AuthenticationTypes.FastBind | AuthenticationTypes.Secure))
  {
    using (DirectorySearcher ds = new DirectorySearcher(e, "(&(objectCategory=inetorgperson)(logonCount=0))"))
    {
      ds.SearchScope = SearchScope.OneLevel;
      ds.PropertiesToLoad.Clear();
      ds.PropertiesToLoad.Add("logonCount");
      ds.PropertiesToLoad.Add("sAMAccountName");


      Stopwatch sw = new Stopwatch();
      sw.Start();
      int countPerson = 0;
      using (SearchResultCollection searchResultCol = ds.FindAll())
      {
        foreach (SearchResult sr in searchResultCol)
        {
          ResultPropertyValueCollection propCol = sr.Properties["logonCount"];

          if (propCol.Count > 0)
          {
            countPerson++;
            object cou = propCol[0];
          }
        }
        sw.Stop();
        Console.Out.WriteLine(sw.ElapsedMilliseconds);
        Console.Out.WriteLine(countPerson);
      }
    }
  }

出于同样的原因,我在搜索过滤器中使用了 objectCategory 而不是 objectClass,因为 objectCategory 是一个所谓的索引属性。访问索引属性比访问非索引属性更快。

此外,我指定了 AuthenticationTypes.FastBind 来提高性能。

要进一步提高性能,请参阅MSDN上的这篇文章,描述如何创建高效的搜索查询。

总而言之,使用 DirectorySearcher 类并仅指定您感兴趣的属性可以极大地提高搜索性能(减少到 Active Directory 的往返行程)。

希望这可以帮助。

于 2011-09-07T20:27:19.010 回答
2

是的你可以; 将每个 Principal 对象的 GetUnderlyingObject() 转换为 DirectoryEntry,然后您可以访问自定义属性,如 oDE.Properties[YOUR_CUSTOM_ATTRIBUTE].Value。

于 2011-09-07T18:46:13.783 回答