gpt4 book ai didi

c# - PrincipalSearcher 和 DirectorySearcher 之间的区别

转载 作者:IT王子 更新时间:2023-10-29 04:20:14 24 4
gpt4 key购买 nike

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

使用 PrincipalSearcher 的示例

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 的例子

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());
}

最佳答案

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

  • DirectorySearcher 来自 System.DirectoryServices 命名空间。

  • PrincipalSearcher 来自 System.DirectoryServices.AccountManagement 命名空间,它建立在 System.DirectoryServices 之上。 PrincipalSearcher 内部使用 DirectorySearcher

  • AccountManagement 命名空间(即 PrincipalSearcher)旨在简化用户、组和计算机对象(即委托(delegate)人)的管理。从理论上讲,它的用法应该更容易理解,并产生更少的代码行。尽管到目前为止,在我的实践中,它似乎在很大程度上取决于你在做什么。

  • DirectorySearcher 更底层,可以处理的不仅仅是用户、组和计算机对象。

  • 对于一般用法,当您使用基本属性和少数对象时,PrincipalSearcher 将导致更少的代码行和更快的运行时间。

  • 您正在执行的任务变得越高级,优势似乎就会消失。例如,如果您期望超过几百个结果,则必须获取基础 DirectorySearcher 并设置 PageSize

    DirectorySearcher ds = search.GetUnderlyingSearcher() as DirectorySearcher;
    if( ds != null )
    ds.PageSize = 1000;
  • 如果您使用 PropertiesToLoad
  • DirectorySearcher 可以比 PrincipalSearcher 快得多。

  • DirectorySearcher 和类似的类可以处理 AD 中的所有对象,而 PrincipalSearcher 的限制要多得多。例如,您不能使用 PrincipalSearcher 和类似类修改组织单位。

这是我使用 PrincipalSearcherDirectorySearcher 而不使用 PropertiesToLoadDirectorySearcher 进行分析的图表使用 PropertiesToLoad。所有测试...

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

DirectorySearcher vs. PrincipalSearcher Performance Chart


每个测试的代码


使用 PrincipalSearcher

[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

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);
}


使用 DirectorySearcherPropertiesToLoad

与“使用 DirectorySearcher 相同,但添加此行

search.PropertiesToLoad.AddRange(new string[] { "canonicalName" });

之后

search.PageSize = 1000;

关于c# - PrincipalSearcher 和 DirectorySearcher 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23176284/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com