SearchResult集合上的部分搜索 - Active Directory,所有组

时间:2016-01-11 18:34:54

标签: c# linq collections active-directory

我有一个存储在以下项目中的活动目录的组名列表: -

SearchResultCollection AllGroupsResults;

 DirectorySearcher ds = null;
 DirectoryEntry de = new DirectoryEntry(domainPath); <--- passed ina
 ds = new DirectorySearcher(de);
 // Sort by name
 ds.Sort = new SortOption("name", SortDirection.Ascending);
 ds.PropertiesToLoad.Add("name");
 ds.Filter = "(&(objectCategory=Group))";
 AllGroupsResults = ds.FindAll();

用户在文本框中输入一个字符串,我想对集合中的组名进行部分匹配,如下所示: -

var partialGroupNameMatches = 
          AllGroupsResults.FindAll(er => er.GroupName.Contains(searchString));

但我的语法不起作用,因为该集合没有定义&#34; FindAll&#34; ...这是否意味着我需要将我的集合转换为自定义列表,还是有另一种我不知道的方式?

**编辑**

var partialGroupNameMatch = AllGroupsResults.Cast<SearchResult>().ToList()
                           .FindAll(o => o.Properties["name"].Contains(searchString));

感谢我的建议,我的语法正确...但是Where或FindAll子句返回的结果是-0 ....即使是像#34; a&#34;或&#34; A&#34; ....

我可以在我的AllGroupsResults集合上设置一个断点,看看它有2个属性&#39; adspath&#39;并且&#39; name&#39; ....两者都有超过5000个值..

令我感到困惑的是: -

 var q2 = AllGroupsResults.Cast<SearchResult>().Select(o => o.Properties["name"]).ToList();
 var partialMatch = q2.Where(o => o.Contains(searchString));

虽然q2 ...包含了GroupNames的所有结果...当我对它进行partialMatch查询时,我得到0结果......无论我的查询字符串是多么通用。

2 个答案:

答案 0 :(得分:1)

SearchResultCollection实现非通用System.Collections.IEnumerable,因此您可以Cast<>()并使用常规LINQ:

var partialGroupNameMatches = 
      AllGroupsResults
          .Cast<SearchResult>()
          .Where(er => er.GroupName.Contains(searchString));

当我尝试此操作时,它告诉我SearchResult没有GroupName属性,因此我猜测SearchResult不正确在此输入。 Ryan Carlisle建议an answer to that question

但现在我们正在谈论name财产。另外,请记住这是AD,所以一切都很糟糕。 sr.Properties["name"]是值的集合,而不是字符串。它和String都有Contains方法,但它们是不同的Contains方法,可以执行不同的操作。因此,当您致电sr.Properties["name"].Contains("a")时,如果其中一个名称是字符串"a",您实际上会询问一组名称。没有,所以它永远不会返回真实。

相反,让我们在该集合中的每个名称上调用Contains

var partialGroupNameMatches = 
      AllGroupsResults
          .Cast<SearchResult>()
          .Where(sr => 
              //  Return true if *any* name contains searchString
              sr.Properties["name"].Cast<String>()
                .Any(s => s.Contains(searchString))
          );

请注意,sr.Properties["name"]集合包含对象,并且它不是LINQ友好的,但只要它实现System.Collections.IEnumerable - 并且几乎所有在阳光下都可以实现,如果它& #39;甚至是远程集合 - 我们Cast我们可以开展业务。

现在我在partialGroupNameMatches获得了预期的结果。

我把剩下的剩下的留给你了!

答案 1 :(得分:1)

方法FindAllList<T>而非ICollection<T>的方法。因此,即使您的SearchResultCollection实施ICollection,也没有任何名为FindAll的方法。有两种选择,我可以为您的问题考虑

  1. 创建List<T>并在其中调用FindAll方法。
  2. 调用Where扩展方法,因为SearchResultCollection实现了IEnumerable