Dre*_*pin 30 c# directoryservices active-directory
我看到使用的Active Directory示例PrincipalSearcher和其他使用相同内容的示例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);
}
Run Code Online (Sandbox Code Playgroud)
使用示例 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());
}
Run Code Online (Sandbox Code Playgroud)
Dre*_*pin 76
我花了很多时间分析这两者之间的差异.这是我学到的.
DirectorySearcher来自System.DirectoryServices命名空间.
PrincipalSearcher来自System.DirectoryServices.AccountManagement命名空间,它建立在System.DirectoryServices.PrincipalSearcher内部使用DirectorySearcher.
该AccountManagement命名空间(即PrincipalSearcher)旨在简化用户,集团的管理和计算机对象(即校长).理论上,它的使用应该更容易理解,并产生更少的代码行.虽然在我的实践中到目前为止,它似乎在很大程度上依赖于你正在做的事情.
DirectorySearcher 更低级别,可以处理不仅仅是用户,组和计算机对象.
对于一般用法,当您使用基本属性和仅少量对象时, PrincipalSearcher将导致更少的代码行和更快的运行时间.
优势似乎消失了,你所做的任务越先进.例如,如果你期望超过几百个结果,你将不得不得到底层DirectorySearcher并设置PageSize
DirectorySearcher ds = search.GetUnderlyingSearcher() as DirectorySearcher;
if( ds != null )
ds.PageSize = 1000;
Run Code Online (Sandbox Code Playgroud)DirectorySearcher可以比PrincipalSearcher你使用时快得多PropertiesToLoad.
DirectorySearcher类似的类可以与AD中的所有对象一起使用,PrincipalSearcher但更有限.例如,您无法使用PrincipalSearcher类似的类修改组织单位.
这是我使用PrincipalSearcher,DirectorySearcher不使用PropertiesToLoad和DirectorySearcher使用分析的图表PropertiesToLoad.所有测试......
PageSize的1000objectClass=userobjectCategory=person!msExchResourceMetaData=ResourceType:Room)!userAccountControl:1.2.840.113556.1.4.803:=2)
运用 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);
}
Run Code Online (Sandbox Code Playgroud)
运用 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);
}
Run Code Online (Sandbox Code Playgroud)
使用DirectorySearcher与PropertiesToLoad
与"使用DirectorySearcher但添加此行相同"
search.PropertiesToLoad.AddRange(new string[] { "canonicalName" });
Run Code Online (Sandbox Code Playgroud)
后
search.PageSize = 1000;
Run Code Online (Sandbox Code Playgroud)
PrincipalSearcher用于查询组或用户的目录。DirectorySearcher用于查询各种对象。
在此之前我曾经DirectorySearcher获得过组,PrincipalSearcher所以当我用后者替换前者时,我的程序的速度提高了(也许这只是PrincipalSearcher为我创建了一个更好的查询。对于我关心的,PrincipalSearcher只是更容易使用和更多适合获取校长的任务。
DirectorySearcher另一方面更通用,因为它可以获取其他类型的对象。这就是为什么它不能像评论中提到的那样被强类型化。PrincipalSearcher都是关于主体的,因此它将具有与主体相关的强类型对象,这就是为什么您也不需要告诉它为您提供类型用户或组的对象,它将由您使用的主体类暗示。
| 归档时间: |
|
| 查看次数: |
19571 次 |
| 最近记录: |