首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PrincipalSearcher与DirectorySearcher的区别

PrincipalSearcher与DirectorySearcher的区别
EN

Stack Overflow用户
提问于 2014-04-19 22:26:40
回答 4查看 28.2K关注 0票数 46

我看到使用PrincipalSearcher的Active示例和其他使用DirectorySearcher的示例。这两个例子有什么区别?

使用PrincipalSearcher的示例

代码语言:javascript
复制
PrincipalContext context = new PrincipalContext(ContextType.Domain);
PrincipalSearcher search = new PrincipalSearcher(new UserPrincipal(context));
foreach( UserPrincipal user in search.FindAll() )
{
    if( null != user )
        Console.WriteLine(user.DistinguishedName);
}

使用DirectorySearcher的示例

代码语言:javascript
复制
DirectorySearcher search = new DirectorySearcher("(&(objectClass=user)(objectCategory=person))");
search.PageSize = 1000;
foreach( SearchResult result in search.FindAll() )
{
    DirectoryEntry user = result.GetDirectoryEntry();
    if( null != user )
        Console.WriteLine(user.Properties["distinguishedName"].Value.ToString());
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-10-12 01:51:17

我花了很多时间分析这两者之间的区别。这是我学到的。

  • DirectorySearcher来自System.DirectoryServices命名空间。
  • PrincipalSearcher来自System.DirectoryServices.AccountManagement命名空间,该名称空间构建在System.DirectoryServices之上。PrincipalSearcher内部使用DirectorySearcher
  • AccountManagement命名空间(即PrincipalSearcher)旨在简化用户、组和计算机对象(即原则)的管理。理论上,它的使用应该更容易理解,并产生较少的代码行。尽管到目前为止,在我的实践中,它似乎在很大程度上取决于你在做什么。
  • DirectorySearcher级别更低,可以处理的不仅仅是用户、组和计算机对象.
  • 对于一般的使用,当您使用基本属性和几个对象时,PrincipalSearcher将减少代码行数和加快运行时间。
  • 你所做的任务越先进,这个优势就会消失。例如,如果您期望获得超过几百个结果,则必须获取基础DirectorySearcher并设置PageSize DirectorySearcher ds = search.GetUnderlyingSearcher()作为DirectorySearcher;if( ds != null ) ds.PageSize = 1000;
  • 如果您使用DirectorySearcher,那么PrincipalSearcherPropertiesToLoad要快得多。
  • DirectorySearcher和like类可以处理AD中的所有对象,而PrincipalSearcher则限制得多。例如,您不能使用PrincipalSearcher和like类修改组织单元。

这是我制作的一个图表,用于使用PrincipalSearcher、不使用PropertiesToLoadDirectorySearcher和使用PropertiesToLoadDirectorySearcher进行分析。所有的测试..。

  • 使用PageSize of 1000
  • 查询总共4 278个用户对象
  • 指定以下条件
    • objectClass=user
    • objectCategory=person
    • 不是调度资源(即!msExchResourceMetaData=ResourceType:Room)
    • 启用(即!userAccountControl:1.2.840.113556.1.4.803:=2)

每个测试的代码

使用PrincipalSearcher

代码语言:javascript
复制
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("Person")]
public class UserPrincipalEx: UserPrincipal
{

    private AdvancedFiltersEx _advancedFilters;

    public UserPrincipalEx( PrincipalContext context ): base(context)
    {
        this.ExtensionSet("objectCategory","User");
    }

    public new AdvancedFiltersEx AdvancedSearchFilter
    {
        get {
            if( null == _advancedFilters )
                _advancedFilters = new AdvancedFiltersEx(this);
                return _advancedFilters;
        }
    }

}

public class AdvancedFiltersEx: AdvancedFilters 
{

    public AdvancedFiltersEx( Principal principal ): 
        base(principal) { }

    public void Person()
    {
        this.AdvancedFilterSet("objectCategory", "person", typeof(string), MatchType.Equals);
        this.AdvancedFilterSet("msExchResourceMetaData", "ResourceType:Room", typeof(string), MatchType.NotEquals);
    }
}

//...

for( int i = 0; i < 10; i++ )
{
    uint count = 0;
    Stopwatch timer = Stopwatch.StartNew();
    PrincipalContext context = new PrincipalContext(ContextType.Domain);
    UserPrincipalEx filter = new UserPrincipalEx(context);
    filter.Enabled = true;
    filter.AdvancedSearchFilter.Person();
    PrincipalSearcher search = new PrincipalSearcher(filter);
    DirectorySearcher ds = search.GetUnderlyingSearcher() as DirectorySearcher;
    if( ds != null )
        ds.PageSize = 1000;
    foreach( UserPrincipalEx result in search.FindAll() )
    {
        string canonicalName = result.CanonicalName;
        count++;
    }

    timer.Stop();
    Console.WriteLine("{0}, {1} ms", count, timer.ElapsedMilliseconds);
}

使用DirectorySearcher

代码语言:javascript
复制
for( int i = 0; i < 10; i++ )
{
    uint count = 0;
    string queryString = "(&(objectClass=user)(objectCategory=person)(!msExchResourceMetaData=ResourceType:Room)(!userAccountControl:1.2.840.113556.1.4.803:=2))";

    Stopwatch timer = Stopwatch.StartNew();

    DirectoryEntry entry = new DirectoryEntry();
    DirectorySearcher search = new DirectorySearcher(entry,queryString);
    search.PageSize = 1000;
    foreach( SearchResult result in search.FindAll() )
    {
        DirectoryEntry user = result.GetDirectoryEntry();
        if( user != null )
        {
            user.RefreshCache(new string[]{"canonicalName"});
            string canonicalName = user.Properties["canonicalName"].Value.ToString();
            count++;
        }
    }
    timer.Stop();
    Console.WriteLine("{0}, {1} ms", count, timer.ElapsedMilliseconds);
}

使用DirectorySearcher PropertiesToLoad

与“使用DirectorySearcher但添加以下行”相同

代码语言:javascript
复制
search.PropertiesToLoad.AddRange(new string[] { "canonicalName" });

之后

代码语言:javascript
复制
search.PageSize = 1000;
票数 110
EN

Stack Overflow用户

发布于 2014-05-17 16:50:16

PrincipalSearcher用于查询目录中的组或用户。DirectorySearcher用于查询各种对象。

在此之前,我使用DirectorySearcher来获取组,所以当我将前者替换为后者时,我的程序速度提高了(也许是PrincipalSearcher为我创建了一个更好的查询。对于我关心的是,PrincipalSearcher只是更容易使用和更适合于获得主语的任务。

另一方面,DirectorySearcher更通用,因为它可以获得其他类型的对象。这就是为什么不能像注释中提到的那样强类型的原因。PrincipalSearcher是关于主体的,所以它将有与主体相关的强类型对象,这也是为什么您也不需要告诉它才能获得类用户或组的对象,它将被您使用的主体类所暗示。

票数 5
EN

Stack Overflow用户

发布于 2019-09-20 04:31:42

DirectorySearcher要快得多。@DrewChapin的例子还可以更进一步。通过我的测试,大约更快了10倍。我能用他的代码在3.8秒内拉出721台电脑cn。相当快。用我的改动,我在0.38秒内完成了。取决于你在做什么,这可能是件大事。我在预测帐户搜索中使用了此方法(开始键入名称并填充一个组合框)。一个非常短的System.Timer开始于每个按键之后,并被一个按键取消。如果计时器过期,列表将更新。效率是巨大的。)

代码语言:javascript
复制
DirectoryEntry entry = new DirectoryEntry();
DirectorySearcher search = new DirectorySearcher(entry,queryString);
search.PageSize = 1000;
// *** Added following line
search.PropertiesToLoad.AddRange(new string[] { "canonicalName" });
foreach( SearchResult result in search.FindAll() )
{
    //DirectoryEntry user = result.GetDirectoryEntry();
    // *** Work directly with result instead of user
    if( result != null )
    {
        //user.RefreshCache(new string[]{"canonicalName"});
        // *** Following line modified
        string canonicalName = result.Properties["canonicalName"][0].ToString();
        count++;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23176284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档